initial commit
This commit is contained in:
87
.github/CLA/ENTITY.md
vendored
Normal file
87
.github/CLA/ENTITY.md
vendored
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
# Contributor Agreement
|
||||||
|
|
||||||
|
## Entity Contributor Exclusive License Agreement
|
||||||
|
|
||||||
|
## (including the Traditional Patent License OPTION)
|
||||||
|
|
||||||
|
Thank you for your interest in contributing to the owners of this code repository ("We" or "Us").
|
||||||
|
|
||||||
|
The purpose of this contributor agreement ("Agreement") is to clarify and document the rights granted by contributors to Us. To make this document effective, please check the box when submitting a Pull Request or an Issue, where applicable.
|
||||||
|
|
||||||
|
### How to use this Contributor Agreement
|
||||||
|
|
||||||
|
If You are an employee and have created the Contribution as part of your employment, You need to have Your employer approve this Agreement or sign the Entity version of this document. If You do not own the Copyright in the entire work of authorship, any other author of the Contribution should also sign this.
|
||||||
|
|
||||||
|
### 1\. Definitions
|
||||||
|
|
||||||
|
**"You"** means the individual Copyright owner who Submits a Contribution to Us.
|
||||||
|
|
||||||
|
**"Legal Entity"** means an entity that is not a natural person.
|
||||||
|
|
||||||
|
**"Affiliate"** means any other Legal Entity that controls, is controlled by, or under common control with that Legal Entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such Legal Entity, whether by contract or otherwise, (ii) ownership of fifty percent (50%) or more of the outstanding shares or securities that vote to elect the management or other persons who direct such Legal Entity or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
**"Contribution"** means any original work of authorship, including any original modifications or additions to an existing work of authorship, Submitted by You to Us, in which You own the Copyright.
|
||||||
|
|
||||||
|
**"Copyright"** means all rights protecting works of authorship, including copyright, moral and neighboring rights, as appropriate, for the full term of their existence.
|
||||||
|
|
||||||
|
**"Material"** means the software or documentation made available by Us to third parties. When this Agreement covers more than one software project, the Material means the software or documentation to which the Contribution was Submitted. After You Submit the Contribution, it may be included in the Material.
|
||||||
|
|
||||||
|
**"Submit"** means any act by which a Contribution is transferred to Us by You by means of tangible or intangible media, including but not limited to electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, Us, but excluding any transfer that is conspicuously marked or otherwise designated in writing by You as "Not a Contribution."
|
||||||
|
|
||||||
|
**"Documentation"** means any non-software portion of a Contribution.
|
||||||
|
|
||||||
|
### 2\. License grant
|
||||||
|
|
||||||
|
#### 2.1 Copyright license to Us
|
||||||
|
|
||||||
|
Subject to the terms and conditions of this Agreement, You hereby grant to Us a worldwide, royalty-free, Exclusive, perpetual and irrevocable (except as stated in Section 8.2) license, with the right to transfer an unlimited number of non-exclusive licenses or to grant sublicenses to third parties, under the Copyright covering the Contribution to use the Contribution by all means, including, but not limited to:
|
||||||
|
|
||||||
|
* publish the Contribution,
|
||||||
|
* modify the Contribution,
|
||||||
|
* prepare derivative works based upon or containing the Contribution and/or to combine the Contribution with other Materials,
|
||||||
|
* reproduce the Contribution in original or modified form,
|
||||||
|
* distribute, to make the Contribution available to the public, display and publicly perform the Contribution in original or modified form.
|
||||||
|
|
||||||
|
#### 2.2 Moral rights
|
||||||
|
|
||||||
|
Moral Rights remain unaffected to the extent they are recognized and not waivable by applicable law. Notwithstanding, You may add your name to the attribution mechanism customary used in the Materials you Contribute to, such as the header of the source code files of Your Contribution, and We will respect this attribution when using Your Contribution.
|
||||||
|
|
||||||
|
### 3\. Patents
|
||||||
|
|
||||||
|
#### 3.1 Patent license
|
||||||
|
|
||||||
|
Subject to the terms and conditions of this Agreement You hereby grant to Us and to recipients of Materials distributed by Us a worldwide, royalty-free, non-exclusive, perpetual and irrevocable (except as stated in Section 3.2) patent license, with the right to transfer an unlimited number of non-exclusive licenses or to grant sublicenses to third parties, to make, have made, use, sell, offer for sale, import and otherwise transfer the Contribution and the Contribution in combination with any Material (and portions of such combination). This license applies to all patents owned or controlled by You, whether already acquired or hereafter acquired, that would be infringed by making, having made, using, selling, offering for sale, importing or otherwise transferring of Your Contribution(s) alone or by combination of Your Contribution(s) with any Material.
|
||||||
|
|
||||||
|
#### 3.2 Revocation of patent license
|
||||||
|
|
||||||
|
You reserve the right to revoke the patent license stated in section 3.1 if We make any infringement claim that is targeted at your Contribution and not asserted for a Defensive Purpose. An assertion of claims of the Patents shall be considered for a "Defensive Purpose" if the claims are asserted against an entity that has filed, maintained, threatened, or voluntarily participated in a patent infringement lawsuit against Us or any of Our licensees.
|
||||||
|
|
||||||
|
### 4. Disclaimer
|
||||||
|
|
||||||
|
THE CONTRIBUTION IS PROVIDED "AS IS". MORE PARTICULARLY, ALL EXPRESS OR IMPLIED WARRANTIES INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTY OF SATISFACTORY QUALITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE EXPRESSLY DISCLAIMED BY YOU TO US AND BY US TO YOU. TO THE EXTENT THAT ANY SUCH WARRANTIES CANNOT BE DISCLAIMED, SUCH WARRANTY IS LIMITED IN DURATION AND EXTENT TO THE MINIMUM PERIOD AND EXTENT PERMITTED BY LAW.
|
||||||
|
|
||||||
|
### 5. Consequential damage waiver
|
||||||
|
|
||||||
|
TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT WILL YOU OR WE BE LIABLE FOR ANY LOSS OF PROFITS, LOSS OF ANTICIPATED SAVINGS, LOSS OF DATA, INDIRECT, SPECIAL, INCIDENTAL, CONSEQUENTIAL AND EXEMPLARY DAMAGES ARISING OUT OF THIS AGREEMENT REGARDLESS OF THE LEGAL OR EQUITABLE THEORY (CONTRACT, TORT OR OTHERWISE) UPON WHICH THE CLAIM IS BASED.
|
||||||
|
|
||||||
|
### 6. Approximation of disclaimer and damage waiver
|
||||||
|
|
||||||
|
IF THE DISCLAIMER AND DAMAGE WAIVER MENTIONED IN SECTION 4. AND SECTION 5. CANNOT BE GIVEN LEGAL EFFECT UNDER APPLICABLE LOCAL LAW, REVIEWING COURTS SHALL APPLY LOCAL LAW THAT MOST CLOSELY APPROXIMATES AN ABSOLUTE WAIVER OF ALL CIVIL OR CONTRACTUAL LIABILITY IN CONNECTION WITH THE CONTRIBUTION.
|
||||||
|
|
||||||
|
### 7. Term
|
||||||
|
|
||||||
|
7.1 This Agreement shall come into effect upon Your acceptance of the terms and conditions.
|
||||||
|
|
||||||
|
7.3 In the event of a termination of this Agreement Sections 4, 5, 6, 7 and 8 shall survive such termination and shall remain in full force thereafter. For the avoidance of doubt, Free and Open Source Software (sub)licenses that have already been granted for Contributions at the date of the termination shall remain in full force after the termination of this Agreement.
|
||||||
|
|
||||||
|
### 8 Miscellaneous
|
||||||
|
|
||||||
|
8.1 This Agreement and all disputes, claims, actions, suits or other proceedings arising out of this agreement or relating in any way to it shall be governed by the laws of the United States of America excluding its private international law provisions.
|
||||||
|
|
||||||
|
8.2 This Agreement sets out the entire agreement between You and Us for Your Contributions to Us and overrides all other agreements or understandings.
|
||||||
|
|
||||||
|
8.3 In case of Your death, this agreement shall continue with Your heirs. In case of more than one heir, all heirs must exercise their rights through a commonly authorized person.
|
||||||
|
|
||||||
|
8.4 If any provision of this Agreement is found void and unenforceable, such provision will be replaced to the extent possible with a provision that comes closest to the meaning of the original provision and that is enforceable. The terms and conditions set forth in this Agreement shall apply notwithstanding any failure of essential purpose of this Agreement or any limited remedy to the maximum extent possible under law.
|
||||||
|
|
||||||
|
8.5 You agree to notify Us of any facts or circumstances of which you become aware that would make this Agreement inaccurate in any respect.
|
||||||
87
.github/CLA/INDIVIDUAL.md
vendored
Normal file
87
.github/CLA/INDIVIDUAL.md
vendored
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
# Contributor Agreement
|
||||||
|
|
||||||
|
## Individual Contributor Exclusive License Agreement
|
||||||
|
|
||||||
|
## (including the Traditional Patent License OPTION)
|
||||||
|
|
||||||
|
Thank you for your interest in contributing to the owners of this code repository ("We" or "Us").
|
||||||
|
|
||||||
|
The purpose of this contributor agreement ("Agreement") is to clarify and document the rights granted by contributors to Us. To make this document effective, please check the box when submitting a Pull Request or an Issue, where applicable.
|
||||||
|
|
||||||
|
### How to use this Contributor Agreement
|
||||||
|
|
||||||
|
If You are an employee and have created the Contribution as part of your employment, You need to have Your employer approve this Agreement or sign the Entity version of this document. If You do not own the Copyright in the entire work of authorship, any other author of the Contribution should also sign this.
|
||||||
|
|
||||||
|
### 1\. Definitions
|
||||||
|
|
||||||
|
**"You"** means the individual Copyright owner who Submits a Contribution to Us.
|
||||||
|
|
||||||
|
**"Legal Entity"** means an entity that is not a natural person.
|
||||||
|
|
||||||
|
**"Affiliate"** means any other Legal Entity that controls, is controlled by, or under common control with that Legal Entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such Legal Entity, whether by contract or otherwise, (ii) ownership of fifty percent (50%) or more of the outstanding shares or securities that vote to elect the management or other persons who direct such Legal Entity or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
**"Contribution"** means any original work of authorship, including any original modifications or additions to an existing work of authorship, Submitted by You to Us, in which You own the Copyright.
|
||||||
|
|
||||||
|
**"Copyright"** means all rights protecting works of authorship, including copyright, moral and neighboring rights, as appropriate, for the full term of their existence.
|
||||||
|
|
||||||
|
**"Material"** means the software or documentation made available by Us to third parties. When this Agreement covers more than one software project, the Material means the software or documentation to which the Contribution was Submitted. After You Submit the Contribution, it may be included in the Material.
|
||||||
|
|
||||||
|
**"Submit"** means any act by which a Contribution is transferred to Us by You by means of tangible or intangible media, including but not limited to electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, Us, but excluding any transfer that is conspicuously marked or otherwise designated in writing by You as "Not a Contribution."
|
||||||
|
|
||||||
|
**"Documentation"** means any non-software portion of a Contribution.
|
||||||
|
|
||||||
|
### 2\. License grant
|
||||||
|
|
||||||
|
#### 2.1 Copyright license to Us
|
||||||
|
|
||||||
|
Subject to the terms and conditions of this Agreement, You hereby grant to Us a worldwide, royalty-free, Exclusive, perpetual and irrevocable (except as stated in Section 8.2) license, with the right to transfer an unlimited number of non-exclusive licenses or to grant sublicenses to third parties, under the Copyright covering the Contribution to use the Contribution by all means, including, but not limited to:
|
||||||
|
|
||||||
|
* publish the Contribution,
|
||||||
|
* modify the Contribution,
|
||||||
|
* prepare derivative works based upon or containing the Contribution and/or to combine the Contribution with other Materials,
|
||||||
|
* reproduce the Contribution in original or modified form,
|
||||||
|
* distribute, to make the Contribution available to the public, display and publicly perform the Contribution in original or modified form.
|
||||||
|
|
||||||
|
#### 2.2 Moral rights
|
||||||
|
|
||||||
|
Moral Rights remain unaffected to the extent they are recognized and not waivable by applicable law. Notwithstanding, You may add your name to the attribution mechanism customary used in the Materials you Contribute to, such as the header of the source code files of Your Contribution, and We will respect this attribution when using Your Contribution.
|
||||||
|
|
||||||
|
### 3\. Patents
|
||||||
|
|
||||||
|
#### 3.1 Patent license
|
||||||
|
|
||||||
|
Subject to the terms and conditions of this Agreement You hereby grant to Us and to recipients of Materials distributed by Us a worldwide, royalty-free, non-exclusive, perpetual and irrevocable (except as stated in Section 3.2) patent license, with the right to transfer an unlimited number of non-exclusive licenses or to grant sublicenses to third parties, to make, have made, use, sell, offer for sale, import and otherwise transfer the Contribution and the Contribution in combination with any Material (and portions of such combination). This license applies to all patents owned or controlled by You, whether already acquired or hereafter acquired, that would be infringed by making, having made, using, selling, offering for sale, importing or otherwise transferring of Your Contribution(s) alone or by combination of Your Contribution(s) with any Material.
|
||||||
|
|
||||||
|
#### 3.2 Revocation of patent license
|
||||||
|
|
||||||
|
You reserve the right to revoke the patent license stated in section 3.1 if We make any infringement claim that is targeted at your Contribution and not asserted for a Defensive Purpose. An assertion of claims of the Patents shall be considered for a "Defensive Purpose" if the claims are asserted against an entity that has filed, maintained, threatened, or voluntarily participated in a patent infringement lawsuit against Us or any of Our licensees.
|
||||||
|
|
||||||
|
### 4. Disclaimer
|
||||||
|
|
||||||
|
THE CONTRIBUTION IS PROVIDED "AS IS". MORE PARTICULARLY, ALL EXPRESS OR IMPLIED WARRANTIES INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTY OF SATISFACTORY QUALITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE EXPRESSLY DISCLAIMED BY YOU TO US AND BY US TO YOU. TO THE EXTENT THAT ANY SUCH WARRANTIES CANNOT BE DISCLAIMED, SUCH WARRANTY IS LIMITED IN DURATION AND EXTENT TO THE MINIMUM PERIOD AND EXTENT PERMITTED BY LAW.
|
||||||
|
|
||||||
|
### 5. Consequential damage waiver
|
||||||
|
|
||||||
|
TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT WILL YOU OR WE BE LIABLE FOR ANY LOSS OF PROFITS, LOSS OF ANTICIPATED SAVINGS, LOSS OF DATA, INDIRECT, SPECIAL, INCIDENTAL, CONSEQUENTIAL AND EXEMPLARY DAMAGES ARISING OUT OF THIS AGREEMENT REGARDLESS OF THE LEGAL OR EQUITABLE THEORY (CONTRACT, TORT OR OTHERWISE) UPON WHICH THE CLAIM IS BASED.
|
||||||
|
|
||||||
|
### 6. Approximation of disclaimer and damage waiver
|
||||||
|
|
||||||
|
IF THE DISCLAIMER AND DAMAGE WAIVER MENTIONED IN SECTION 4. AND SECTION 5. CANNOT BE GIVEN LEGAL EFFECT UNDER APPLICABLE LOCAL LAW, REVIEWING COURTS SHALL APPLY LOCAL LAW THAT MOST CLOSELY APPROXIMATES AN ABSOLUTE WAIVER OF ALL CIVIL OR CONTRACTUAL LIABILITY IN CONNECTION WITH THE CONTRIBUTION.
|
||||||
|
|
||||||
|
### 7. Term
|
||||||
|
|
||||||
|
7.1 This Agreement shall come into effect upon Your acceptance of the terms and conditions.
|
||||||
|
|
||||||
|
7.3 In the event of a termination of this Agreement Sections 4, 5, 6, 7 and 8 shall survive such termination and shall remain in full force thereafter. For the avoidance of doubt, Free and Open Source Software (sub)licenses that have already been granted for Contributions at the date of the termination shall remain in full force after the termination of this Agreement.
|
||||||
|
|
||||||
|
### 8 Miscellaneous
|
||||||
|
|
||||||
|
8.1 This Agreement and all disputes, claims, actions, suits or other proceedings arising out of this agreement or relating in any way to it shall be governed by the laws of the United States of America excluding its private international law provisions.
|
||||||
|
|
||||||
|
8.2 This Agreement sets out the entire agreement between You and Us for Your Contributions to Us and overrides all other agreements or understandings.
|
||||||
|
|
||||||
|
8.3 In case of Your death, this agreement shall continue with Your heirs. In case of more than one heir, all heirs must exercise their rights through a commonly authorized person.
|
||||||
|
|
||||||
|
8.4 If any provision of this Agreement is found void and unenforceable, such provision will be replaced to the extent possible with a provision that comes closest to the meaning of the original provision and that is enforceable. The terms and conditions set forth in this Agreement shall apply notwithstanding any failure of essential purpose of this Agreement or any limited remedy to the maximum extent possible under law.
|
||||||
|
|
||||||
|
8.5 You agree to notify Us of any facts or circumstances of which you become aware that would make this Agreement inaccurate in any respect.
|
||||||
50
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
50
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
---
|
||||||
|
name: Bug Report
|
||||||
|
description: The following form provides context for your submitted issue.
|
||||||
|
title: '[Bug]: '
|
||||||
|
labels:
|
||||||
|
- review
|
||||||
|
- bug
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
Thanks for taking the time to fill out the below report.
|
||||||
|
- type: input
|
||||||
|
id: version
|
||||||
|
attributes:
|
||||||
|
label: Version, or commit number if you are using a branch and stipulate your fork if one exists
|
||||||
|
description: "If you are running on a branch using git execute this command in order to fetch the latest commit ID: `git log -1`. Please also stipulate if you are using a forked version and include a link to the fork source code."
|
||||||
|
placeholder: "0.1"
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: what-happened
|
||||||
|
attributes:
|
||||||
|
label: What happened?
|
||||||
|
description: Also tell us, what did you expect to happen?
|
||||||
|
placeholder: A clear and concise description of what the bug is. Please include screenshots where relevant.
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: reproduce
|
||||||
|
attributes:
|
||||||
|
label: How To Reproduce
|
||||||
|
description: How can we reproduce this issue? (as minimally and as precisely as possible)
|
||||||
|
placeholder: A clear and concise description of how to reproduce the issue.
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: logs
|
||||||
|
attributes:
|
||||||
|
label: Relevant log output
|
||||||
|
description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
|
||||||
|
render: shell
|
||||||
|
- type: checkboxes
|
||||||
|
id: terms
|
||||||
|
attributes:
|
||||||
|
label: Code of Conduct
|
||||||
|
description: By submitting this issue, you agree to follow our Code of Conduct as defined in `/CODE_OF_CONDUCT.md`.
|
||||||
|
options:
|
||||||
|
- label: I agree to follow this project's Code of Conduct
|
||||||
|
required: true
|
||||||
2
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
2
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
|
||||||
|
blank_issues_enabled: false
|
||||||
53
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
Normal file
53
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
name: Feature Request
|
||||||
|
description: The following form provides context for your requested feature.
|
||||||
|
title: '[Enhancement]: '
|
||||||
|
labels:
|
||||||
|
- review
|
||||||
|
- enhancement
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
Thanks for taking the time to fill out the below report.
|
||||||
|
- type: input
|
||||||
|
id: version
|
||||||
|
attributes:
|
||||||
|
label: Version, or commit number if you are using a branch and stipulate your fork if one exists
|
||||||
|
description: "If you are running on a branch using git execute this command in order to fetch the latest commit ID: `git log -1`. Please also stipulate if you are using a forked version and include a link to the fork source code."
|
||||||
|
placeholder: "0.1"
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: problem
|
||||||
|
attributes:
|
||||||
|
label: Is your feature request related to a problem?
|
||||||
|
placeholder: A clear and concise description of what the problem is. Ex. I'm always frustrated when
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: solution
|
||||||
|
attributes:
|
||||||
|
label: Describe the solution you'd like
|
||||||
|
placeholder: A clear and concise description of what you want to happen.
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: alternatives
|
||||||
|
attributes:
|
||||||
|
label: Describe alternatives you've considered
|
||||||
|
placeholder: A clear and concise description of any alternative solutions or features you've considered.
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: context
|
||||||
|
attributes:
|
||||||
|
label: Additional context
|
||||||
|
placeholder: Add any other context or screenshots about the feature request here.
|
||||||
|
- type: checkboxes
|
||||||
|
id: terms
|
||||||
|
attributes:
|
||||||
|
label: Code of Conduct
|
||||||
|
description: By submitting this issue, you agree to follow our Code of Conduct as defined in `/CODE_OF_CONDUCT.md`.
|
||||||
|
options:
|
||||||
|
- label: I agree to follow this project's Code of Conduct
|
||||||
|
required: true
|
||||||
21
.github/pull_request_template.md
vendored
Normal file
21
.github/pull_request_template.md
vendored
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<!---
|
||||||
|
|
||||||
|
Thanks for taking the time to fill out the below information about your PR.
|
||||||
|
|
||||||
|
--->
|
||||||
|
|
||||||
|
## What does this PR do?
|
||||||
|
Explain the motivation behind your PR. Provide a clear and concise description of what the PR is. Please include screenshots where relevant.
|
||||||
|
|
||||||
|
## Why is this change important?
|
||||||
|
Explain the motivation behind your PR.
|
||||||
|
|
||||||
|
## How to test this PR locally?
|
||||||
|
Commands to run the tests or instructions to test the changes
|
||||||
|
|
||||||
|
<!---
|
||||||
|
|
||||||
|
By submitting this PR, you agree to follow our Code of Conduct as defined in `/CODE_OF_CONDUCT.md`.
|
||||||
|
By submitting this PR, you are agreeing to the Contributor Agreement(s) as defined in links from `/CONTRIBUTING.md`.
|
||||||
|
|
||||||
|
--->
|
||||||
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
node_modules
|
||||||
|
dist
|
||||||
133
CODE_OF_CONDUCT.md
Normal file
133
CODE_OF_CONDUCT.md
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
|
||||||
|
# Contributor Covenant Code of Conduct
|
||||||
|
|
||||||
|
## Our Pledge
|
||||||
|
|
||||||
|
We as members, contributors, and leaders pledge to make participation in our
|
||||||
|
community a harassment-free experience for everyone, regardless of age, body
|
||||||
|
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
||||||
|
identity and expression, level of experience, education, socio-economic status,
|
||||||
|
nationality, personal appearance, race, caste, color, religion, or sexual
|
||||||
|
identity and orientation.
|
||||||
|
|
||||||
|
We pledge to act and interact in ways that contribute to an open, welcoming,
|
||||||
|
diverse, inclusive, and healthy community.
|
||||||
|
|
||||||
|
## Our Standards
|
||||||
|
|
||||||
|
Examples of behavior that contributes to a positive environment for our
|
||||||
|
community include:
|
||||||
|
|
||||||
|
* Demonstrating empathy and kindness toward other people
|
||||||
|
* Being respectful of differing opinions, viewpoints, and experiences
|
||||||
|
* Giving and gracefully accepting constructive feedback
|
||||||
|
* Accepting responsibility and apologizing to those affected by our mistakes,
|
||||||
|
and learning from the experience
|
||||||
|
* Focusing on what is best not just for us as individuals, but for the overall
|
||||||
|
community
|
||||||
|
|
||||||
|
Examples of unacceptable behavior include:
|
||||||
|
|
||||||
|
* The use of sexualized language or imagery, and sexual attention or advances of
|
||||||
|
any kind
|
||||||
|
* Trolling, insulting or derogatory comments, and personal or political attacks
|
||||||
|
* Public or private harassment
|
||||||
|
* Publishing others' private information, such as a physical or email address,
|
||||||
|
without their explicit permission
|
||||||
|
* Other conduct which could reasonably be considered inappropriate in a
|
||||||
|
professional setting
|
||||||
|
|
||||||
|
## Enforcement Responsibilities
|
||||||
|
|
||||||
|
Community leaders are responsible for clarifying and enforcing our standards of
|
||||||
|
acceptable behavior and will take appropriate and fair corrective action in
|
||||||
|
response to any behavior that they deem inappropriate, threatening, offensive,
|
||||||
|
or harmful.
|
||||||
|
|
||||||
|
Community leaders have the right and responsibility to remove, edit, or reject
|
||||||
|
comments, commits, code, wiki edits, issues, and other contributions that are
|
||||||
|
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
||||||
|
decisions when appropriate.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
This Code of Conduct applies within all community spaces, and also applies when
|
||||||
|
an individual is officially representing the community in public spaces.
|
||||||
|
Examples of representing our community include using an official email address,
|
||||||
|
posting via an official social media account, or acting as an appointed
|
||||||
|
representative at an online or offline event.
|
||||||
|
|
||||||
|
## Enforcement
|
||||||
|
|
||||||
|
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||||
|
reported to the community leaders responsible for enforcement.
|
||||||
|
All complaints will be reviewed and investigated promptly and fairly.
|
||||||
|
|
||||||
|
All community leaders are obligated to respect the privacy and security of the
|
||||||
|
reporter of any incident.
|
||||||
|
|
||||||
|
## Enforcement Guidelines
|
||||||
|
|
||||||
|
Community leaders will follow these Community Impact Guidelines in determining
|
||||||
|
the consequences for any action they deem in violation of this Code of Conduct:
|
||||||
|
|
||||||
|
### 1. Correction
|
||||||
|
|
||||||
|
**Community Impact**: Use of inappropriate language or other behavior deemed
|
||||||
|
unprofessional or unwelcome in the community.
|
||||||
|
|
||||||
|
**Consequence**: A private, written warning from community leaders, providing
|
||||||
|
clarity around the nature of the violation and an explanation of why the
|
||||||
|
behavior was inappropriate. A public apology may be requested.
|
||||||
|
|
||||||
|
### 2. Warning
|
||||||
|
|
||||||
|
**Community Impact**: A violation through a single incident or series of
|
||||||
|
actions.
|
||||||
|
|
||||||
|
**Consequence**: A warning with consequences for continued behavior. No
|
||||||
|
interaction with the people involved, including unsolicited interaction with
|
||||||
|
those enforcing the Code of Conduct, for a specified period of time. This
|
||||||
|
includes avoiding interactions in community spaces as well as external channels
|
||||||
|
like social media. Violating these terms may lead to a temporary or permanent
|
||||||
|
ban.
|
||||||
|
|
||||||
|
### 3. Temporary Ban
|
||||||
|
|
||||||
|
**Community Impact**: A serious violation of community standards, including
|
||||||
|
sustained inappropriate behavior.
|
||||||
|
|
||||||
|
**Consequence**: A temporary ban from any sort of interaction or public
|
||||||
|
communication with the community for a specified period of time. No public or
|
||||||
|
private interaction with the people involved, including unsolicited interaction
|
||||||
|
with those enforcing the Code of Conduct, is allowed during this period.
|
||||||
|
Violating these terms may lead to a permanent ban.
|
||||||
|
|
||||||
|
### 4. Permanent Ban
|
||||||
|
|
||||||
|
**Community Impact**: Demonstrating a pattern of violation of community
|
||||||
|
standards, including sustained inappropriate behavior, harassment of an
|
||||||
|
individual, or aggression toward or disparagement of classes of individuals.
|
||||||
|
|
||||||
|
**Consequence**: A permanent ban from any sort of public interaction within the
|
||||||
|
community.
|
||||||
|
|
||||||
|
## Attribution
|
||||||
|
|
||||||
|
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
||||||
|
version 2.1, available at
|
||||||
|
[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
|
||||||
|
|
||||||
|
Community Impact Guidelines were inspired by
|
||||||
|
[Mozilla's code of conduct enforcement ladder][Mozilla CoC].
|
||||||
|
|
||||||
|
For answers to common questions about this code of conduct, see the FAQ at
|
||||||
|
[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at
|
||||||
|
[https://www.contributor-covenant.org/translations][translations].
|
||||||
|
|
||||||
|
[homepage]: https://www.contributor-covenant.org
|
||||||
|
[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
|
||||||
|
[Mozilla CoC]: https://github.com/mozilla/diversity
|
||||||
|
[FAQ]: https://www.contributor-covenant.org/faq
|
||||||
|
[translations]: https://www.contributor-covenant.org/translations
|
||||||
|
|
||||||
6
CONTRIBUTING.md
Normal file
6
CONTRIBUTING.md
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# Contribution Guidelines
|
||||||
|
|
||||||
|
Thank you for contributing! Before you contribute, we ask some things of you:
|
||||||
|
|
||||||
|
- Please follow our Code of Conduct, the Contributor Covenant. You can find a copy [in this repository](CODE_OF_CONDUCT.md) or under https://www.contributor-covenant.org/
|
||||||
|
- All Contributors must agree to [a CLA](.github/CLA/INDIVIDUAL.md). When opening a PR, the system will guide you through the process. However, if you contribute on behalf of a legal entity, we ask of you to agree to [a different CLA](.github/CLA/ENTITY.md). In that case, please contact us.
|
||||||
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2025 JLINC Labs
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
79
README.md
Normal file
79
README.md
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
<p align="center">
|
||||||
|
<img src="./assets/logo.svg" width="600">
|
||||||
|
</p>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
# JLINC Langchain Tracer
|
||||||
|
|
||||||
|
The JLINC Langchain Tracer is the official way to implement the zero-knowledge third-party auditing provided by the [JLINC Server](https://gitea.jlinc.io/jlinc-labs/jlinc-server) inside any Langchain-based infrastructure.
|
||||||
|
|
||||||
|
By embedding JLINC’s trusted protocol directly into Langchain’s tracing system, organizations can prove compliance, accountability, and data integrity without ever exposing sensitive information. This seamless integration enables developers to track, verify, and audit model interactions with full transparency while preserving confidentiality through cryptographically verifiable zero-knowledge proofs. Whether for regulated industries, enterprise governance, or AI safety applications, the JLINC Langchain Tracer ensures that trust, privacy, and accountability are built in from the ground up.
|
||||||
|
|
||||||
|
## Sample application
|
||||||
|
The below code sample is a demonstration of the JLINC Langchain Tracer in action. As data moves through the chain, it is cryptographically signed with a unique key for each element in the chain, and zero-knowledge audit records are delivered to the JLINC Archive Server.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const { ChatOpenAI } = require("@langchain/openai");
|
||||||
|
const { awaitAllCallbacks } = require("@langchain/core/callbacks/promises");
|
||||||
|
const { Calculator } = require("@langchain/community/tools/calculator");
|
||||||
|
const { AgentExecutor, createToolCallingAgent } = require("langchain/agents");
|
||||||
|
const { ChatPromptTemplate } = require("@langchain/core/prompts");
|
||||||
|
const { JLINCTracer } = require("../src/tracer.js");
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
const tracer = new JLINCTracer({
|
||||||
|
dataStoreApiUrl: "http://localhost:9090",
|
||||||
|
dataStoreApiKey: process.env.JLINC_DATA_STORE_API_KEY,
|
||||||
|
archiveApiUrl: "http://localhost:9090",
|
||||||
|
archiveApiKey: process.env.JLINC_ARCHIVE_API_KEY,
|
||||||
|
agreementId: "00000000-0000-0000-0000-000000000000",
|
||||||
|
systemPrefix: "TracerTest",
|
||||||
|
debug: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
const llm = new ChatOpenAI({
|
||||||
|
openAIApiKey: "n/a",
|
||||||
|
configuration: {
|
||||||
|
baseURL: "http://localhost:1234/v1",
|
||||||
|
},
|
||||||
|
modelName: "meta-llama-3.1-8b-instruct",
|
||||||
|
});
|
||||||
|
|
||||||
|
const calculator = new Calculator();
|
||||||
|
const tools = [calculator];
|
||||||
|
|
||||||
|
const prompt = ChatPromptTemplate.fromMessages([
|
||||||
|
["system", "You are a helpful assistant"],
|
||||||
|
["placeholder", "{chat_history}"],
|
||||||
|
["human", "{input}"],
|
||||||
|
["placeholder", "{agent_scratchpad}"],
|
||||||
|
]);
|
||||||
|
|
||||||
|
const agent = createToolCallingAgent({ llm, tools, prompt });
|
||||||
|
|
||||||
|
const agentExecutor = new AgentExecutor({
|
||||||
|
agent,
|
||||||
|
tools,
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
const r = await agentExecutor.invoke({ input: "Add 1 + 1" }, {callbacks: [tracer]});
|
||||||
|
console.log(`\nResult`)
|
||||||
|
console.log(`---------------------------------------------`)
|
||||||
|
console.log(r)
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Error calling LLM:", err);
|
||||||
|
} finally {
|
||||||
|
await awaitAllCallbacks();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
main()
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Additional information
|
||||||
|
|
||||||
|
Full JLINC Documentation: https://docs.jlinc.io
|
||||||
|
|
||||||
|
Details of the JLINC protocol, schema, and context can be found at: https://protocol.jlinc.org/.
|
||||||
1
assets/logo.svg
Normal file
1
assets/logo.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 362.08 100.47"><defs><style>.cls-1{fill:#fff;}.cls-2{fill:#31a9ba;}</style></defs><title>JLINC Logo H White</title><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><path class="cls-1" d="M157.32,29.36h8.35V57.2q0,13.9-13.92,13.91H137.84q-14.22,0-14-13.91l0-1.4h8.35v.25q0,6.72,6.68,6.71h11.66q6.7,0,6.71-6.73Z"/><path class="cls-1" d="M223.12,62.76v8.35H181.37V29.36h8.35v33.4Z"/><path class="cls-1" d="M247.18,71.11h-8.35V29.36h8.35Z"/><path class="cls-1" d="M271.23,42V71.11h-8.35V29.36h8.51l24.89,29.09V29.36h8.35V71.11h-8.49Z"/><path class="cls-1" d="M362.08,62.76v8.35H334.25q-13.92,0-13.92-13.91V43.28q0-13.92,13.92-13.92h27.83v8.35H335.39q-6.7,0-6.71,6.68V56.05q0,6.72,6.74,6.71Z"/><path class="cls-2" d="M8.52,41.22l9,9L36.46,69.16l7.76-7.76L25.3,42.48l-9.42-9.42q-4.5-4.52-5.14-9.26c-.48-3.11,1-6.36,4.35-9.73Q19.22,9.95,23.64,10t9.26,4.83l4,4,7.2-7.21L38.52,6a20.93,20.93,0,0,0-7.91-4.9A17.1,17.1,0,0,0,20,.61Q14,2,8.05,8a28.56,28.56,0,0,0-6.33,9.5,18.2,18.2,0,0,0-.79,11.4Q2.34,35,8.52,41.22Z"/><path class="cls-2" d="M61.4,56.25,42.48,75.17l-9.42,9.42q-4.52,4.51-9.26,5.14t-9.73-4.35Q9.95,81.27,10,76.83t4.83-9.26l4-3.95-7.21-7.21L6,62a21,21,0,0,0-4.9,7.92A17.09,17.09,0,0,0,.61,80.48q1.43,6,7.36,12a28.87,28.87,0,0,0,9.5,6.33,18.2,18.2,0,0,0,11.4.79Q35,98.13,41.22,92l9-9L69.16,64Z"/><path class="cls-2" d="M92,59.26l-9-9L64,31.31l-7.76,7.76L75.17,58l9.42,9.42q4.51,4.52,5.14,9.26t-4.35,9.74c-2.74,2.74-5.59,4.12-8.55,4.11s-6-1.55-9.26-4.83l-3.95-4-7.21,7.2L62,94.48a21.11,21.11,0,0,0,7.92,4.91,17.06,17.06,0,0,0,10.6.47q6-1.42,12-7.36A28.87,28.87,0,0,0,98.76,83a18.16,18.16,0,0,0,.79-11.39Q98.13,65.43,92,59.26Z"/><path class="cls-2" d="M39.07,44.22,58,25.3l9.42-9.42q4.52-4.5,9.26-5.14c3.12-.48,6.36,1,9.74,4.35,2.74,2.75,4.11,5.59,4.11,8.55s-1.55,6-4.83,9.26l-4,4,7.2,7.2,5.54-5.54a21.07,21.07,0,0,0,4.91-7.91A17.17,17.17,0,0,0,99.86,20Q98.44,14,92.5,8.05A28.56,28.56,0,0,0,83,1.72,18.19,18.19,0,0,0,71.6.93Q65.44,2.34,59.26,8.52l-9,9L31.31,36.46Z"/></g></g></svg>
|
||||||
|
After Width: | Height: | Size: 2.0 KiB |
2951
package-lock.json
generated
Normal file
2951
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
28
package.json
Normal file
28
package.json
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"name": "jlinc-tracer",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"description": "A LangChain callback plugin that logs events to the JLINC API.",
|
||||||
|
"main": "dist/tracer.js",
|
||||||
|
"types": "dist/tracer.d.ts",
|
||||||
|
"scripts": {
|
||||||
|
"test": "node test/test_tracer.js",
|
||||||
|
"build": "tsc && cp src/tracer.js dist/"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"jlinc",
|
||||||
|
"langchain",
|
||||||
|
"plugin",
|
||||||
|
"tracer"
|
||||||
|
],
|
||||||
|
"author": "Ben Curtis",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"axios": "^1.6.0",
|
||||||
|
"langchain": "^0.3.29"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@langchain/community": "^0.3.48",
|
||||||
|
"nodemon": "^3.1.10",
|
||||||
|
"typescript": "^5.8.3"
|
||||||
|
}
|
||||||
|
}
|
||||||
241
src/tracer.js
Normal file
241
src/tracer.js
Normal file
@@ -0,0 +1,241 @@
|
|||||||
|
const { LangChainTracer } = require("@langchain/core/tracers/tracer_langchain");
|
||||||
|
const axios = require("axios");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {Object} JLINCTracerFields
|
||||||
|
* @property {string} [dataStoreApiUrl]
|
||||||
|
* @property {string} [dataStoreApiKey]
|
||||||
|
* @property {string} [archiveApiUrl]
|
||||||
|
* @property {string} [archiveApiKey]
|
||||||
|
* @property {string} [systemPrefix]
|
||||||
|
* @property {string|null} [agreementId]
|
||||||
|
* @property {boolean} [debug]
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {Object} SerializedRun
|
||||||
|
* @property {string} [name]
|
||||||
|
* @property {number} [start_time]
|
||||||
|
* @property {number} [end_time]
|
||||||
|
* @property {string} [trace_id]
|
||||||
|
* @property {any} [inputs]
|
||||||
|
* @property {any} [outputs]
|
||||||
|
* @property {{ metadata?: { ls_provider?: string, ls_model_name?: string } }} [extra]
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @extends {LangChainTracer}
|
||||||
|
*/
|
||||||
|
class JLINCTracer extends LangChainTracer {
|
||||||
|
/**
|
||||||
|
* @param {JLINCTracerFields} [fields={}]
|
||||||
|
*/
|
||||||
|
constructor(fields = {}) {
|
||||||
|
super(fields);
|
||||||
|
const defaultDataStoreApiUrl = "https://api-test.jlinc.io";
|
||||||
|
const defaultDataStoreApiKey = "";
|
||||||
|
const defaultArchiveApiUrl = "https://archive-test.jlinc.io";
|
||||||
|
const defaultArchiveApiKey = "";
|
||||||
|
const defaultSystemPrefix = "MyProject";
|
||||||
|
|
||||||
|
/** @type {string} */
|
||||||
|
this.dataStoreApiUrl = fields.dataStoreApiUrl ?? defaultDataStoreApiUrl;
|
||||||
|
/** @type {string} */
|
||||||
|
this.dataStoreApiKey = fields.dataStoreApiKey ?? defaultDataStoreApiKey;
|
||||||
|
/** @type {string} */
|
||||||
|
this.archiveApiUrl = fields.archiveApiUrl ?? defaultArchiveApiUrl;
|
||||||
|
/** @type {string} */
|
||||||
|
this.archiveApiKey = fields.archiveApiKey ?? defaultArchiveApiKey;
|
||||||
|
/** @type {string} */
|
||||||
|
this.systemPrefix = this._sanitize(fields.systemPrefix ?? defaultSystemPrefix);
|
||||||
|
/** @type {string|null} */
|
||||||
|
this.agreementId = fields.agreementId ?? null;
|
||||||
|
/** @type {boolean} */
|
||||||
|
this.debug = fields.debug ?? false;
|
||||||
|
|
||||||
|
/** @type {string|null} */
|
||||||
|
this.domain = null;
|
||||||
|
/** @type {Set<string>} */
|
||||||
|
this.entities = new Set();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {any} run
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
async onRunCreate(run) { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {any} run
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
async onRunUpdate(run) { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
async getDefaultProjectName() {
|
||||||
|
return this.systemPrefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {SerializedRun} serialized
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
async onLLMStart(serialized) {
|
||||||
|
if (this.debug) {
|
||||||
|
console.log(`\nJLINC: onLLMStart`);
|
||||||
|
console.log(`---------------------------------------------`);
|
||||||
|
}
|
||||||
|
await this._jlincTrace({
|
||||||
|
event: "llm_start",
|
||||||
|
name: serialized?.name || "unknown",
|
||||||
|
ts: serialized?.start_time,
|
||||||
|
provider: serialized?.extra?.metadata,
|
||||||
|
traceId: serialized?.trace_id,
|
||||||
|
inputs: serialized?.inputs,
|
||||||
|
}, 'out');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {SerializedRun} serialized
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
async onLLMEnd(serialized) {
|
||||||
|
if (this.debug) {
|
||||||
|
console.log(`\nJLINC: onLLMEnd`);
|
||||||
|
console.log(`---------------------------------------------`);
|
||||||
|
}
|
||||||
|
await this._jlincTrace({
|
||||||
|
event: "llm_end",
|
||||||
|
name: serialized?.name || "unknown",
|
||||||
|
ts: serialized?.end_time,
|
||||||
|
provider: serialized?.extra?.metadata,
|
||||||
|
traceId: serialized?.trace_id,
|
||||||
|
outputs: serialized?.outputs,
|
||||||
|
}, 'in');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {SerializedRun} serialized
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
async onToolStart(serialized) {
|
||||||
|
if (this.debug) {
|
||||||
|
console.log(`\nJLINC: onToolStart`);
|
||||||
|
console.log(`---------------------------------------------`);
|
||||||
|
}
|
||||||
|
await this._jlincTrace({
|
||||||
|
event: "tool_start",
|
||||||
|
name: serialized?.name || "unknown",
|
||||||
|
ts: serialized?.start_time,
|
||||||
|
provider: serialized?.extra?.metadata,
|
||||||
|
traceId: serialized?.trace_id,
|
||||||
|
inputs: serialized?.inputs,
|
||||||
|
}, 'out');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {SerializedRun} serialized
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
async onToolEnd(serialized) {
|
||||||
|
if (this.debug) {
|
||||||
|
console.log(`\nJLINC: onToolEnd`);
|
||||||
|
console.log(`---------------------------------------------`);
|
||||||
|
}
|
||||||
|
await this._jlincTrace({
|
||||||
|
event: "tool_end",
|
||||||
|
name: serialized?.name || "unknown",
|
||||||
|
ts: serialized?.end_time,
|
||||||
|
provider: serialized?.extra?.metadata,
|
||||||
|
traceId: serialized?.trace_id,
|
||||||
|
outputs: serialized?.outputs,
|
||||||
|
}, 'in');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} dir
|
||||||
|
* @param {any} payload
|
||||||
|
* @returns {Promise<any>}
|
||||||
|
*/
|
||||||
|
async _postToApi(dir, payload) {
|
||||||
|
const response = await axios.post(
|
||||||
|
`${this.dataStoreApiUrl}/api/v1/data/${dir}`,
|
||||||
|
payload,
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
'Authorization': `Bearer ${this.dataStoreApiKey}`,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
return response.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} entityShortName
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
async _setEntity(entityShortName) {
|
||||||
|
if (!this.entities.has(entityShortName)) {
|
||||||
|
let recipient = null;
|
||||||
|
try {
|
||||||
|
recipient = await this._postToApi(`entity/get`, { shortName: entityShortName });
|
||||||
|
} catch (e) {
|
||||||
|
recipient = await this._postToApi(`entity/create`, { shortName: entityShortName });
|
||||||
|
}
|
||||||
|
this.entities.add(entityShortName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} input
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
_sanitize(input) {
|
||||||
|
return input.replace(/[^a-zA-Z0-9._-]/g, '_');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {any} payload
|
||||||
|
* @param {'in' | 'out'} direction
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
async _jlincTrace(payload, direction) {
|
||||||
|
try {
|
||||||
|
if (!this.domain) {
|
||||||
|
const domains = await this._postToApi(`entity/domains/get`, {});
|
||||||
|
this.domain = domains[0];
|
||||||
|
}
|
||||||
|
let entityShortName = `${this.systemPrefix}-${this._sanitize(payload.name)}`;
|
||||||
|
payload?.provider?.ls_provider && (entityShortName += `-${this._sanitize(payload.provider.ls_provider)}`);
|
||||||
|
payload?.provider?.ls_model_name && (entityShortName += `-${this._sanitize(payload.provider.ls_model_name)}`);
|
||||||
|
entityShortName += `@${this.domain}`;
|
||||||
|
await this._setEntity(entityShortName);
|
||||||
|
const systemShortName = `${this.systemPrefix}-system@${this.domain}`;
|
||||||
|
await this._setEntity(systemShortName);
|
||||||
|
const recipientShortName = direction === 'in' ? systemShortName : entityShortName;
|
||||||
|
const senderShortName = direction === 'out' ? systemShortName : entityShortName;
|
||||||
|
const data = {
|
||||||
|
type: 'data',
|
||||||
|
senderShortName,
|
||||||
|
recipientShortName,
|
||||||
|
agreementId: this.agreementId,
|
||||||
|
data: payload,
|
||||||
|
archive: {
|
||||||
|
url: this.archiveApiUrl,
|
||||||
|
key: this.archiveApiKey,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const event = await this._postToApi(`event/produce`, data);
|
||||||
|
if (this.debug) {
|
||||||
|
console.log(JSON.stringify({ event }, null, 2));
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("[Tracer] Failed to log event:", error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { JLINCTracer }
|
||||||
56
test/test_tracer.js
Normal file
56
test/test_tracer.js
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
const { ChatOpenAI } = require("@langchain/openai");
|
||||||
|
const { awaitAllCallbacks } = require("@langchain/core/callbacks/promises");
|
||||||
|
const { Calculator } = require("@langchain/community/tools/calculator");
|
||||||
|
const { AgentExecutor, createToolCallingAgent } = require("langchain/agents");
|
||||||
|
const { ChatPromptTemplate } = require("@langchain/core/prompts");
|
||||||
|
const { JLINCTracer } = require("../src/tracer.js");
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
const tracer = new JLINCTracer({
|
||||||
|
dataStoreApiUrl: "http://localhost:9090",
|
||||||
|
dataStoreApiKey: process.env.JLINC_DATA_STORE_API_KEY,
|
||||||
|
archiveApiUrl: "http://localhost:9090",
|
||||||
|
archiveApiKey: process.env.JLINC_ARCHIVE_API_KEY,
|
||||||
|
agreementId: "00000000-0000-0000-0000-000000000000",
|
||||||
|
systemPrefix: "TracerTest",
|
||||||
|
debug: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
const llm = new ChatOpenAI({
|
||||||
|
openAIApiKey: "n/a",
|
||||||
|
configuration: {
|
||||||
|
baseURL: "http://localhost:1234/v1",
|
||||||
|
},
|
||||||
|
modelName: "meta-llama-3.1-8b-instruct",
|
||||||
|
});
|
||||||
|
|
||||||
|
const calculator = new Calculator();
|
||||||
|
const tools = [calculator];
|
||||||
|
|
||||||
|
const prompt = ChatPromptTemplate.fromMessages([
|
||||||
|
["system", "You are a helpful assistant"],
|
||||||
|
["placeholder", "{chat_history}"],
|
||||||
|
["human", "{input}"],
|
||||||
|
["placeholder", "{agent_scratchpad}"],
|
||||||
|
]);
|
||||||
|
|
||||||
|
const agent = createToolCallingAgent({ llm, tools, prompt });
|
||||||
|
|
||||||
|
const agentExecutor = new AgentExecutor({
|
||||||
|
agent,
|
||||||
|
tools,
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
const r = await agentExecutor.invoke({ input: "Add 1 + 1" }, {callbacks: [tracer]});
|
||||||
|
console.log(`\nResult`)
|
||||||
|
console.log(`---------------------------------------------`)
|
||||||
|
console.log(r)
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Error calling LLM:", err);
|
||||||
|
} finally {
|
||||||
|
await awaitAllCallbacks();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
main()
|
||||||
16
tsconfig.json
Normal file
16
tsconfig.json
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"allowJs": true,
|
||||||
|
"declaration": true,
|
||||||
|
"emitDeclarationOnly": true,
|
||||||
|
"outDir": "dist",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"target": "ESNext",
|
||||||
|
"module": "ESNext",
|
||||||
|
"strict": true,
|
||||||
|
"esModuleInterop": true
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"src"
|
||||||
|
]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user