Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2d68f29ab5 | ||
|
|
19d4a93bca | ||
|
|
fb75c5f44e | ||
|
|
52af987985 | ||
|
|
162a30acdd | ||
|
|
898a6fc638 | ||
|
|
38e2362be4 | ||
|
|
cea912d0b5 | ||
|
|
5ec00040c2 | ||
|
|
8d28fc4a0d | ||
|
|
7cc6587724 | ||
|
|
bacf76e0a9 | ||
|
|
f86c7bfd57 | ||
|
|
2aaf340575 | ||
|
|
bae11ba85c | ||
|
|
9eb7d8912c | ||
|
|
d29535245f | ||
|
|
ca3ae982b0 | ||
|
|
0c4399b46c | ||
|
|
c13ef1921d | ||
|
|
0fb9acfa8f | ||
|
|
2ac4389e1a | ||
|
|
de194e425c | ||
|
|
95f3d6506e | ||
|
|
3e877243b9 | ||
|
|
fd795c9e90 | ||
|
|
5f5dc041b9 | ||
|
|
3d3885d43d | ||
|
|
b059744716 | ||
|
|
f2a41aaa2c | ||
|
|
1fcf751d0d | ||
|
|
a45c9407fd | ||
|
|
21fdf108cf | ||
|
|
c7ec2b3ea4 | ||
|
|
6c4da6cea5 | ||
|
|
3029c5dd26 | ||
|
|
3e97028094 | ||
|
|
1194c87134 | ||
|
|
e03b5315c2 | ||
|
|
fad887492f | ||
|
|
f26df29937 | ||
|
|
69b54a08ba | ||
|
|
7ce77eb18e | ||
|
|
1480669dc8 | ||
|
|
f397bbffe7 | ||
|
|
5709bce1ae | ||
|
|
d549a36c3a | ||
|
|
e9ba480e95 | ||
|
|
8ac7154399 | ||
|
|
f25f2db885 | ||
|
|
621732ae0a | ||
|
|
ed85c659be | ||
|
|
f6dcd1c382 | ||
|
|
37c572fd98 | ||
|
|
1ff709d05c | ||
|
|
83726feae1 | ||
|
|
f24c87cc51 | ||
|
|
1c40968a94 | ||
|
|
c37ec7c1dd | ||
|
|
ff3e600302 |
@@ -1,22 +1,437 @@
|
|||||||
MIT License
|
Attribution-NonCommercial-ShareAlike 4.0 International
|
||||||
|
|
||||||
Copyright (c) 2024 smkrv
|
=======================================================================
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Creative Commons Corporation ("Creative Commons") is not a law firm and
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
does not provide legal services or legal advice. Distribution of
|
||||||
in the Software without restriction, including without limitation the rights
|
Creative Commons public licenses does not create a lawyer-client or
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
other relationship. Creative Commons makes its licenses and related
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
information available on an "as-is" basis. Creative Commons gives no
|
||||||
furnished to do so, subject to the following conditions:
|
warranties regarding its licenses, any material licensed under their
|
||||||
|
terms and conditions, or any related information. Creative Commons
|
||||||
|
disclaims all liability for damages resulting from their use to the
|
||||||
|
fullest extent possible.
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
Using Creative Commons Public Licenses
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
Creative Commons public licenses provide a standard set of terms and
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
conditions that creators and other rights holders may use to share
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
original works of authorship and other material subject to copyright
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
and certain other rights specified in the public license below. The
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
following considerations are for informational purposes only, are not
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
exhaustive, and do not form part of our licenses.
|
||||||
SOFTWARE.
|
|
||||||
|
Considerations for licensors: Our public licenses are
|
||||||
|
intended for use by those authorized to give the public
|
||||||
|
permission to use material in ways otherwise restricted by
|
||||||
|
copyright and certain other rights. Our licenses are
|
||||||
|
irrevocable. Licensors should read and understand the terms
|
||||||
|
and conditions of the license they choose before applying it.
|
||||||
|
Licensors should also secure all rights necessary before
|
||||||
|
applying our licenses so that the public can reuse the
|
||||||
|
material as expected. Licensors should clearly mark any
|
||||||
|
material not subject to the license. This includes other CC-
|
||||||
|
licensed material, or material used under an exception or
|
||||||
|
limitation to copyright. More considerations for licensors:
|
||||||
|
wiki.creativecommons.org/Considerations_for_licensors
|
||||||
|
|
||||||
|
Considerations for the public: By using one of our public
|
||||||
|
licenses, a licensor grants the public permission to use the
|
||||||
|
licensed material under specified terms and conditions. If
|
||||||
|
the licensor's permission is not necessary for any reason--for
|
||||||
|
example, because of any applicable exception or limitation to
|
||||||
|
copyright--then that use is not regulated by the license. Our
|
||||||
|
licenses grant only permissions under copyright and certain
|
||||||
|
other rights that a licensor has authority to grant. Use of
|
||||||
|
the licensed material may still be restricted for other
|
||||||
|
reasons, including because others have copyright or other
|
||||||
|
rights in the material. A licensor may make special requests,
|
||||||
|
such as asking that all changes be marked or described.
|
||||||
|
Although not required by our licenses, you are encouraged to
|
||||||
|
respect those requests where reasonable. More considerations
|
||||||
|
for the public:
|
||||||
|
wiki.creativecommons.org/Considerations_for_licensees
|
||||||
|
|
||||||
|
=======================================================================
|
||||||
|
|
||||||
|
Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International
|
||||||
|
Public License
|
||||||
|
|
||||||
|
By exercising the Licensed Rights (defined below), You accept and agree
|
||||||
|
to be bound by the terms and conditions of this Creative Commons
|
||||||
|
Attribution-NonCommercial-ShareAlike 4.0 International Public License
|
||||||
|
("Public License"). To the extent this Public License may be
|
||||||
|
interpreted as a contract, You are granted the Licensed Rights in
|
||||||
|
consideration of Your acceptance of these terms and conditions, and the
|
||||||
|
Licensor grants You such rights in consideration of benefits the
|
||||||
|
Licensor receives from making the Licensed Material available under
|
||||||
|
these terms and conditions.
|
||||||
|
|
||||||
|
|
||||||
|
Section 1 -- Definitions.
|
||||||
|
|
||||||
|
a. Adapted Material means material subject to Copyright and Similar
|
||||||
|
Rights that is derived from or based upon the Licensed Material
|
||||||
|
and in which the Licensed Material is translated, altered,
|
||||||
|
arranged, transformed, or otherwise modified in a manner requiring
|
||||||
|
permission under the Copyright and Similar Rights held by the
|
||||||
|
Licensor. For purposes of this Public License, where the Licensed
|
||||||
|
Material is a musical work, performance, or sound recording,
|
||||||
|
Adapted Material is always produced where the Licensed Material is
|
||||||
|
synched in timed relation with a moving image.
|
||||||
|
|
||||||
|
b. Adapter's License means the license You apply to Your Copyright
|
||||||
|
and Similar Rights in Your contributions to Adapted Material in
|
||||||
|
accordance with the terms and conditions of this Public License.
|
||||||
|
|
||||||
|
c. BY-NC-SA Compatible License means a license listed at
|
||||||
|
creativecommons.org/compatiblelicenses, approved by Creative
|
||||||
|
Commons as essentially the equivalent of this Public License.
|
||||||
|
|
||||||
|
d. Copyright and Similar Rights means copyright and/or similar rights
|
||||||
|
closely related to copyright including, without limitation,
|
||||||
|
performance, broadcast, sound recording, and Sui Generis Database
|
||||||
|
Rights, without regard to how the rights are labeled or
|
||||||
|
categorized. For purposes of this Public License, the rights
|
||||||
|
specified in Section 2(b)(1)-(2) are not Copyright and Similar
|
||||||
|
Rights.
|
||||||
|
|
||||||
|
e. Effective Technological Measures means those measures that, in the
|
||||||
|
absence of proper authority, may not be circumvented under laws
|
||||||
|
fulfilling obligations under Article 11 of the WIPO Copyright
|
||||||
|
Treaty adopted on December 20, 1996, and/or similar international
|
||||||
|
agreements.
|
||||||
|
|
||||||
|
f. Exceptions and Limitations means fair use, fair dealing, and/or
|
||||||
|
any other exception or limitation to Copyright and Similar Rights
|
||||||
|
that applies to Your use of the Licensed Material.
|
||||||
|
|
||||||
|
g. License Elements means the license attributes listed in the name
|
||||||
|
of a Creative Commons Public License. The License Elements of this
|
||||||
|
Public License are Attribution, NonCommercial, and ShareAlike.
|
||||||
|
|
||||||
|
h. Licensed Material means the artistic or literary work, database,
|
||||||
|
or other material to which the Licensor applied this Public
|
||||||
|
License.
|
||||||
|
|
||||||
|
i. Licensed Rights means the rights granted to You subject to the
|
||||||
|
terms and conditions of this Public License, which are limited to
|
||||||
|
all Copyright and Similar Rights that apply to Your use of the
|
||||||
|
Licensed Material and that the Licensor has authority to license.
|
||||||
|
|
||||||
|
j. Licensor means the individual(s) or entity(ies) granting rights
|
||||||
|
under this Public License.
|
||||||
|
|
||||||
|
k. NonCommercial means not primarily intended for or directed towards
|
||||||
|
commercial advantage or monetary compensation. For purposes of
|
||||||
|
this Public License, the exchange of the Licensed Material for
|
||||||
|
other material subject to Copyright and Similar Rights by digital
|
||||||
|
file-sharing or similar means is NonCommercial provided there is
|
||||||
|
no payment of monetary compensation in connection with the
|
||||||
|
exchange.
|
||||||
|
|
||||||
|
l. Share means to provide material to the public by any means or
|
||||||
|
process that requires permission under the Licensed Rights, such
|
||||||
|
as reproduction, public display, public performance, distribution,
|
||||||
|
dissemination, communication, or importation, and to make material
|
||||||
|
available to the public including in ways that members of the
|
||||||
|
public may access the material from a place and at a time
|
||||||
|
individually chosen by them.
|
||||||
|
|
||||||
|
m. Sui Generis Database Rights means rights other than copyright
|
||||||
|
resulting from Directive 96/9/EC of the European Parliament and of
|
||||||
|
the Council of 11 March 1996 on the legal protection of databases,
|
||||||
|
as amended and/or succeeded, as well as other essentially
|
||||||
|
equivalent rights anywhere in the world.
|
||||||
|
|
||||||
|
n. You means the individual or entity exercising the Licensed Rights
|
||||||
|
under this Public License. Your has a corresponding meaning.
|
||||||
|
|
||||||
|
|
||||||
|
Section 2 -- Scope.
|
||||||
|
|
||||||
|
a. License grant.
|
||||||
|
|
||||||
|
1. Subject to the terms and conditions of this Public License,
|
||||||
|
the Licensor hereby grants You a worldwide, royalty-free,
|
||||||
|
non-sublicensable, non-exclusive, irrevocable license to
|
||||||
|
exercise the Licensed Rights in the Licensed Material to:
|
||||||
|
|
||||||
|
a. reproduce and Share the Licensed Material, in whole or
|
||||||
|
in part, for NonCommercial purposes only; and
|
||||||
|
|
||||||
|
b. produce, reproduce, and Share Adapted Material for
|
||||||
|
NonCommercial purposes only.
|
||||||
|
|
||||||
|
2. Exceptions and Limitations. For the avoidance of doubt, where
|
||||||
|
Exceptions and Limitations apply to Your use, this Public
|
||||||
|
License does not apply, and You do not need to comply with
|
||||||
|
its terms and conditions.
|
||||||
|
|
||||||
|
3. Term. The term of this Public License is specified in Section
|
||||||
|
6(a).
|
||||||
|
|
||||||
|
4. Media and formats; technical modifications allowed. The
|
||||||
|
Licensor authorizes You to exercise the Licensed Rights in
|
||||||
|
all media and formats whether now known or hereafter created,
|
||||||
|
and to make technical modifications necessary to do so. The
|
||||||
|
Licensor waives and/or agrees not to assert any right or
|
||||||
|
authority to forbid You from making technical modifications
|
||||||
|
necessary to exercise the Licensed Rights, including
|
||||||
|
technical modifications necessary to circumvent Effective
|
||||||
|
Technological Measures. For purposes of this Public License,
|
||||||
|
simply making modifications authorized by this Section 2(a)
|
||||||
|
(4) never produces Adapted Material.
|
||||||
|
|
||||||
|
5. Downstream recipients.
|
||||||
|
|
||||||
|
a. Offer from the Licensor -- Licensed Material. Every
|
||||||
|
recipient of the Licensed Material automatically
|
||||||
|
receives an offer from the Licensor to exercise the
|
||||||
|
Licensed Rights under the terms and conditions of this
|
||||||
|
Public License.
|
||||||
|
|
||||||
|
b. Additional offer from the Licensor -- Adapted Material.
|
||||||
|
Every recipient of Adapted Material from You
|
||||||
|
automatically receives an offer from the Licensor to
|
||||||
|
exercise the Licensed Rights in the Adapted Material
|
||||||
|
under the conditions of the Adapter's License You apply.
|
||||||
|
|
||||||
|
c. No downstream restrictions. You may not offer or impose
|
||||||
|
any additional or different terms or conditions on, or
|
||||||
|
apply any Effective Technological Measures to, the
|
||||||
|
Licensed Material if doing so restricts exercise of the
|
||||||
|
Licensed Rights by any recipient of the Licensed
|
||||||
|
Material.
|
||||||
|
|
||||||
|
6. No endorsement. Nothing in this Public License constitutes or
|
||||||
|
may be construed as permission to assert or imply that You
|
||||||
|
are, or that Your use of the Licensed Material is, connected
|
||||||
|
with, or sponsored, endorsed, or granted official status by,
|
||||||
|
the Licensor or others designated to receive attribution as
|
||||||
|
provided in Section 3(a)(1)(A)(i).
|
||||||
|
|
||||||
|
b. Other rights.
|
||||||
|
|
||||||
|
1. Moral rights, such as the right of integrity, are not
|
||||||
|
licensed under this Public License, nor are publicity,
|
||||||
|
privacy, and/or other similar personality rights; however, to
|
||||||
|
the extent possible, the Licensor waives and/or agrees not to
|
||||||
|
assert any such rights held by the Licensor to the limited
|
||||||
|
extent necessary to allow You to exercise the Licensed
|
||||||
|
Rights, but not otherwise.
|
||||||
|
|
||||||
|
2. Patent and trademark rights are not licensed under this
|
||||||
|
Public License.
|
||||||
|
|
||||||
|
3. To the extent possible, the Licensor waives any right to
|
||||||
|
collect royalties from You for the exercise of the Licensed
|
||||||
|
Rights, whether directly or through a collecting society
|
||||||
|
under any voluntary or waivable statutory or compulsory
|
||||||
|
licensing scheme. In all other cases the Licensor expressly
|
||||||
|
reserves any right to collect such royalties, including when
|
||||||
|
the Licensed Material is used other than for NonCommercial
|
||||||
|
purposes.
|
||||||
|
|
||||||
|
|
||||||
|
Section 3 -- License Conditions.
|
||||||
|
|
||||||
|
Your exercise of the Licensed Rights is expressly made subject to the
|
||||||
|
following conditions.
|
||||||
|
|
||||||
|
a. Attribution.
|
||||||
|
|
||||||
|
1. If You Share the Licensed Material (including in modified
|
||||||
|
form), You must:
|
||||||
|
|
||||||
|
a. retain the following if it is supplied by the Licensor
|
||||||
|
with the Licensed Material:
|
||||||
|
|
||||||
|
i. identification of the creator(s) of the Licensed
|
||||||
|
Material and any others designated to receive
|
||||||
|
attribution, in any reasonable manner requested by
|
||||||
|
the Licensor (including by pseudonym if
|
||||||
|
designated);
|
||||||
|
|
||||||
|
ii. a copyright notice;
|
||||||
|
|
||||||
|
iii. a notice that refers to this Public License;
|
||||||
|
|
||||||
|
iv. a notice that refers to the disclaimer of
|
||||||
|
warranties;
|
||||||
|
|
||||||
|
v. a URI or hyperlink to the Licensed Material to the
|
||||||
|
extent reasonably practicable;
|
||||||
|
|
||||||
|
b. indicate if You modified the Licensed Material and
|
||||||
|
retain an indication of any previous modifications; and
|
||||||
|
|
||||||
|
c. indicate the Licensed Material is licensed under this
|
||||||
|
Public License, and include the text of, or the URI or
|
||||||
|
hyperlink to, this Public License.
|
||||||
|
|
||||||
|
2. You may satisfy the conditions in Section 3(a)(1) in any
|
||||||
|
reasonable manner based on the medium, means, and context in
|
||||||
|
which You Share the Licensed Material. For example, it may be
|
||||||
|
reasonable to satisfy the conditions by providing a URI or
|
||||||
|
hyperlink to a resource that includes the required
|
||||||
|
information.
|
||||||
|
3. If requested by the Licensor, You must remove any of the
|
||||||
|
information required by Section 3(a)(1)(A) to the extent
|
||||||
|
reasonably practicable.
|
||||||
|
|
||||||
|
b. ShareAlike.
|
||||||
|
|
||||||
|
In addition to the conditions in Section 3(a), if You Share
|
||||||
|
Adapted Material You produce, the following conditions also apply.
|
||||||
|
|
||||||
|
1. The Adapter's License You apply must be a Creative Commons
|
||||||
|
license with the same License Elements, this version or
|
||||||
|
later, or a BY-NC-SA Compatible License.
|
||||||
|
|
||||||
|
2. You must include the text of, or the URI or hyperlink to, the
|
||||||
|
Adapter's License You apply. You may satisfy this condition
|
||||||
|
in any reasonable manner based on the medium, means, and
|
||||||
|
context in which You Share Adapted Material.
|
||||||
|
|
||||||
|
3. You may not offer or impose any additional or different terms
|
||||||
|
or conditions on, or apply any Effective Technological
|
||||||
|
Measures to, Adapted Material that restrict exercise of the
|
||||||
|
rights granted under the Adapter's License You apply.
|
||||||
|
|
||||||
|
|
||||||
|
Section 4 -- Sui Generis Database Rights.
|
||||||
|
|
||||||
|
Where the Licensed Rights include Sui Generis Database Rights that
|
||||||
|
apply to Your use of the Licensed Material:
|
||||||
|
|
||||||
|
a. for the avoidance of doubt, Section 2(a)(1) grants You the right
|
||||||
|
to extract, reuse, reproduce, and Share all or a substantial
|
||||||
|
portion of the contents of the database for NonCommercial purposes
|
||||||
|
only;
|
||||||
|
|
||||||
|
b. if You include all or a substantial portion of the database
|
||||||
|
contents in a database in which You have Sui Generis Database
|
||||||
|
Rights, then the database in which You have Sui Generis Database
|
||||||
|
Rights (but not its individual contents) is Adapted Material,
|
||||||
|
including for purposes of Section 3(b); and
|
||||||
|
|
||||||
|
c. You must comply with the conditions in Section 3(a) if You Share
|
||||||
|
all or a substantial portion of the contents of the database.
|
||||||
|
|
||||||
|
For the avoidance of doubt, this Section 4 supplements and does not
|
||||||
|
replace Your obligations under this Public License where the Licensed
|
||||||
|
Rights include other Copyright and Similar Rights.
|
||||||
|
|
||||||
|
|
||||||
|
Section 5 -- Disclaimer of Warranties and Limitation of Liability.
|
||||||
|
|
||||||
|
a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
|
||||||
|
EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
|
||||||
|
AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
|
||||||
|
ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
|
||||||
|
IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
|
||||||
|
WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
|
||||||
|
ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
|
||||||
|
KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
|
||||||
|
ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
|
||||||
|
|
||||||
|
b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
|
||||||
|
TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
|
||||||
|
NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
|
||||||
|
INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
|
||||||
|
COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
|
||||||
|
USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
|
||||||
|
ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
|
||||||
|
DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
|
||||||
|
IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
|
||||||
|
|
||||||
|
c. The disclaimer of warranties and limitation of liability provided
|
||||||
|
above shall be interpreted in a manner that, to the extent
|
||||||
|
possible, most closely approximates an absolute disclaimer and
|
||||||
|
waiver of all liability.
|
||||||
|
|
||||||
|
|
||||||
|
Section 6 -- Term and Termination.
|
||||||
|
|
||||||
|
a. This Public License applies for the term of the Copyright and
|
||||||
|
Similar Rights licensed here. However, if You fail to comply with
|
||||||
|
this Public License, then Your rights under this Public License
|
||||||
|
terminate automatically.
|
||||||
|
|
||||||
|
b. Where Your right to use the Licensed Material has terminated under
|
||||||
|
Section 6(a), it reinstates:
|
||||||
|
|
||||||
|
1. automatically as of the date the violation is cured, provided
|
||||||
|
it is cured within 30 days of Your discovery of the
|
||||||
|
violation; or
|
||||||
|
|
||||||
|
2. upon express reinstatement by the Licensor.
|
||||||
|
|
||||||
|
For the avoidance of doubt, this Section 6(b) does not affect any
|
||||||
|
right the Licensor may have to seek remedies for Your violations
|
||||||
|
of this Public License.
|
||||||
|
|
||||||
|
c. For the avoidance of doubt, the Licensor may also offer the
|
||||||
|
Licensed Material under separate terms or conditions or stop
|
||||||
|
distributing the Licensed Material at any time; however, doing so
|
||||||
|
will not terminate this Public License.
|
||||||
|
|
||||||
|
d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
|
||||||
|
License.
|
||||||
|
|
||||||
|
|
||||||
|
Section 7 -- Other Terms and Conditions.
|
||||||
|
|
||||||
|
a. The Licensor shall not be bound by any additional or different
|
||||||
|
terms or conditions communicated by You unless expressly agreed.
|
||||||
|
|
||||||
|
b. Any arrangements, understandings, or agreements regarding the
|
||||||
|
Licensed Material not stated herein are separate from and
|
||||||
|
independent of the terms and conditions of this Public License.
|
||||||
|
|
||||||
|
|
||||||
|
Section 8 -- Interpretation.
|
||||||
|
|
||||||
|
a. For the avoidance of doubt, this Public License does not, and
|
||||||
|
shall not be interpreted to, reduce, limit, restrict, or impose
|
||||||
|
conditions on any use of the Licensed Material that could lawfully
|
||||||
|
be made without permission under this Public License.
|
||||||
|
|
||||||
|
b. To the extent possible, if any provision of this Public License is
|
||||||
|
deemed unenforceable, it shall be automatically reformed to the
|
||||||
|
minimum extent necessary to make it enforceable. If the provision
|
||||||
|
cannot be reformed, it shall be severed from this Public License
|
||||||
|
without affecting the enforceability of the remaining terms and
|
||||||
|
conditions.
|
||||||
|
|
||||||
|
c. No term or condition of this Public License will be waived and no
|
||||||
|
failure to comply consented to unless expressly agreed to by the
|
||||||
|
Licensor.
|
||||||
|
|
||||||
|
d. Nothing in this Public License constitutes or may be interpreted
|
||||||
|
as a limitation upon, or waiver of, any privileges and immunities
|
||||||
|
that apply to the Licensor or You, including from the legal
|
||||||
|
processes of any jurisdiction or authority.
|
||||||
|
|
||||||
|
=======================================================================
|
||||||
|
|
||||||
|
Creative Commons is not a party to its public
|
||||||
|
licenses. Notwithstanding, Creative Commons may elect to apply one of
|
||||||
|
its public licenses to material it publishes and in those instances
|
||||||
|
will be considered the “Licensor.” The text of the Creative Commons
|
||||||
|
public licenses is dedicated to the public domain under the CC0 Public
|
||||||
|
Domain Dedication. Except for the limited purpose of indicating that
|
||||||
|
material is shared under a Creative Commons public license or as
|
||||||
|
otherwise permitted by the Creative Commons policies published at
|
||||||
|
creativecommons.org/policies, Creative Commons does not authorize the
|
||||||
|
use of the trademark "Creative Commons" or any other trademark or logo
|
||||||
|
of Creative Commons without its prior written consent including,
|
||||||
|
without limitation, in connection with any unauthorized modifications
|
||||||
|
to any of its public licenses or any other arrangements,
|
||||||
|
understandings, or agreements concerning use of licensed material. For
|
||||||
|
the avoidance of doubt, this paragraph does not form part of the
|
||||||
|
public licenses.
|
||||||
|
|
||||||
|
Creative Commons may be contacted at creativecommons.org.
|
||||||
|
|||||||
@@ -2,11 +2,11 @@
|
|||||||
|
|
||||||
<div align="center">
|
<div align="center">
|
||||||
|
|
||||||
  [](https://opensource.org/licenses/MIT) [](https://github.com/hacs/integration)   
|
  [](https://creativecommons.org/licenses/by-nc-sa/4.0/) [](https://github.com/hacs/integration)   
|
||||||
|
|
||||||
<img src="https://github.com/smkrv/ha-text-ai/blob/524849f6a945ec62c2cf6a6b7ecd9a28b37bf0fa/misc/icons/logo.jpg" alt="HA Text AI" height="160"/>
|
<img src="https://github.com/smkrv/ha-text-ai/blob/2aaf3405759eb2d97624834594e24ace896131df/assets/images/icons/logo.png" alt="HA Text AI" style="width: 80%; max-width: 640px; max-height: 150px; aspect-ratio: 2/1; object-fit: contain;"/>
|
||||||
|
|
||||||
### Advanced AI Integration for Home Assistant with LLM multi-provider support
|
### Advanced AI Integration for [Home Assistant](https://www.home-assistant.io/) with LLM multi-provider support
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
@@ -17,61 +17,88 @@ Transform your smart home experience with powerful AI assistance powered by mult
|
|||||||
---
|
---
|
||||||
|
|
||||||
> [!IMPORTANT]
|
> [!IMPORTANT]
|
||||||
> 🚧 ALPHA VERSION 🚧
|
|
||||||
> Expect: potential bugs, frequent changes, incomplete features.
|
|
||||||
> 🤝 Community Driven
|
> 🤝 Community Driven
|
||||||
>
|
>
|
||||||
> <a href="https://community.home-assistant.io/t/ha-text-ai-transforming-home-automation-with-multi-provider-language-models/799741"><img src="https://img.shields.io/badge/Community-blue?style=for-the-badge&logo=homeassistant&logoColor=white&color=03a9f4"/></a>
|
> <a href="https://community.home-assistant.io/t/ha-text-ai-transforming-home-automation-with-multi-provider-language-models/799741"><img src="https://img.shields.io/badge/Community-blue?style=for-the-badge&logo=homeassistant&logoColor=white&color=03a9f4"/></a>
|
||||||
|
>
|
||||||
|
> [Screenshots](assets/images/screenshots/screenshot.jpg)
|
||||||
|
|
||||||
## 🌟 Features
|
## 🌟 Features
|
||||||
|
|
||||||
- 🧠 **Multi-Provider AI Integration**:
|
- 🧠 **Multi-Provider AI Integration**: Support for OpenAI GPT and Anthropic Claude models
|
||||||
- Support for OpenAI GPT models
|
- 💬 **Advanced Language Processing**: Context-aware, multi-turn conversations
|
||||||
- Anthropic Claude integration
|
- 📝 **Enhanced Memory Management**: Secure file-based history storage
|
||||||
- Custom API endpoints
|
- ⚡ **Performance Optimization**: Efficient token usage and smart rate limiting
|
||||||
- Flexible model selection
|
- 🎯 **Advanced Customization**: Per-request model and parameter selection
|
||||||
|
- 🔒 **Enhanced Security**: Secure API key management and usage monitoring
|
||||||
|
- 🎨 **Improved User Experience**: Intuitive configuration and rich interfaces
|
||||||
|
- 🔄 **Automation Integration**: Event-driven responses and template compatibility
|
||||||
|
|
||||||
- 💬 **Advanced Language Processing**:
|
<details>
|
||||||
- Context-aware responses
|
<summary>📦 Detailed Feature Breakdown</summary>
|
||||||
- Multi-turn conversations
|
|
||||||
- Custom system instructions
|
|
||||||
- Natural conversation flow
|
|
||||||
|
|
||||||
- 📝 **Enhanced Memory Management**:
|
### 🧠 **Multi-Provider AI Integration**
|
||||||
- Persistent conversation history
|
- Support for OpenAI GPT models
|
||||||
- Context-aware responses
|
- Anthropic Claude integration
|
||||||
- Customizable history limits
|
- Custom API endpoints
|
||||||
- Model-specific filtering
|
- Flexible model selection
|
||||||
|
|
||||||
- ⚡ **Performance Optimization**:
|
### 💬 **Advanced Language Processing**
|
||||||
- Efficient token usage
|
- Context-aware responses
|
||||||
- Smart rate limiting
|
- Multi-turn conversations
|
||||||
- Response caching
|
- Custom system instructions
|
||||||
- Request interval control
|
- Natural conversation flow
|
||||||
|
|
||||||
- 🎯 **Advanced Customization**:
|
### 📝 **Enhanced Memory Management**
|
||||||
- Per-request model selection
|
- File-based conversation history storage
|
||||||
- Adjustable parameters
|
- Automatic history rotation
|
||||||
- Custom system prompts
|
- Configurable history size limits
|
||||||
- Temperature control
|
- Secure storage in Home Assistant
|
||||||
|
|
||||||
- 🔒 **Enhanced Security**:
|
### ⚡ **Performance Optimization**
|
||||||
- Secure API key storage
|
- Efficient token usage
|
||||||
- Rate limiting protection
|
- Smart rate limiting
|
||||||
- Error handling
|
- Response caching
|
||||||
- Usage monitoring
|
- Request interval control
|
||||||
|
|
||||||
- 🎨 **Improved User Experience**:
|
### 🎯 **Advanced Customization**
|
||||||
- Intuitive configuration UI
|
- Per-request model selection
|
||||||
- Detailed sensor attributes
|
- Adjustable parameters
|
||||||
- Rich service interface
|
- Custom system prompts
|
||||||
- Model selection UI
|
- Temperature control
|
||||||
|
|
||||||
- 🔄 **Automation Integration**:
|
### 🔒 **Enhanced Security**
|
||||||
- Event-driven responses
|
- Secure API key storage
|
||||||
- Conditional logic support
|
- Rate limiting protection
|
||||||
- Template compatibility
|
- Error handling
|
||||||
- Model-specific automation
|
- Usage monitoring
|
||||||
|
|
||||||
|
### 🎨 **Improved User Experience**
|
||||||
|
- Intuitive configuration UI
|
||||||
|
- Detailed sensor attributes
|
||||||
|
- Rich service interface
|
||||||
|
- Model selection UI
|
||||||
|
|
||||||
|
### 🔄 **Automation Integration**
|
||||||
|
- Event-driven responses
|
||||||
|
- Conditional logic support
|
||||||
|
- Template compatibility
|
||||||
|
- Model-specific automation
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
#### 🌐 Translations
|
||||||
|
|
||||||
|
| Code | Language | Status |
|
||||||
|
|------|----------|--------|
|
||||||
|
| 🇩🇪 de | Deutsch | Full |
|
||||||
|
| 🇬🇧 en | English | Primary |
|
||||||
|
| 🇪🇸 es | Español | Full |
|
||||||
|
| 🇮🇳 hi | हिन्दी | Full |
|
||||||
|
| 🇮🇹 it | Italiano | Full |
|
||||||
|
| 🇷🇺 ru | Русский | Full |
|
||||||
|
| 🇷🇸 sr | Српски | Full |
|
||||||
|
| 🇨🇳 zh | 中文 | Full |
|
||||||
|
|
||||||
## 📋 Prerequisites
|
## 📋 Prerequisites
|
||||||
|
|
||||||
@@ -80,41 +107,50 @@ Transform your smart home experience with powerful AI assistance powered by mult
|
|||||||
- OpenAI ([Get key](https://platform.openai.com/account/api-keys))
|
- OpenAI ([Get key](https://platform.openai.com/account/api-keys))
|
||||||
- Anthropic ([Get key](https://console.anthropic.com/))
|
- Anthropic ([Get key](https://console.anthropic.com/))
|
||||||
- OpenRouter ([Get key](https://openrouter.ai/keys))
|
- OpenRouter ([Get key](https://openrouter.ai/keys))
|
||||||
|
- Any OpenAI-compatible API provider
|
||||||
- Python 3.9 or newer
|
- Python 3.9 or newer
|
||||||
- Stable internet connection
|
- Stable internet connection
|
||||||
|
|
||||||
### Configuration Options
|
## Configuration Options
|
||||||
- API Provider (OpenAI/Anthropic)
|
|
||||||
- API Key (provider-specific)
|
|
||||||
- Model Selection (flexible, provider-specific models)
|
|
||||||
- Temperature (Creativity control, 0.0-2.0)
|
|
||||||
- Max Tokens (Response length limit)
|
|
||||||
- Request Interval (API call throttling)
|
|
||||||
- Custom API Endpoint (optional)
|
|
||||||
|
|
||||||
#### ⓘ Potentially Compatible Providers
|
### 🔧 **Core Configuration Settings**
|
||||||
The integration is designed to be flexible and may work with other providers offering OpenAI-compatible APIs:
|
- 🌐 **API Provider**: OpenAI/Anthropic
|
||||||
- Groq
|
- 🔑 **API Key**: Provider-specific authentication
|
||||||
- Together AI
|
- 🤖 **Model Selection**: Flexible, provider-specific models
|
||||||
- Perplexity AI
|
- 🌡️ **Temperature**: Creativity control (0.0-2.0)
|
||||||
- Mistral AI
|
- 📏 **Max Tokens**: Response length limit (token usage is estimated using a heuristic method based on word count and specific word characteristics, which may differ from actual token usage)
|
||||||
- Google AI
|
- ⏱️ **Request Interval**: API call throttling
|
||||||
- Local AI servers (like Ollama)
|
- 💾 **History Size**: Number of messages to retain
|
||||||
- Custom OpenAI-compatible endpoints
|
- 🌍 **Custom API Endpoint**: Optional advanced configuration
|
||||||
|
|
||||||
#### Additional Notes
|
<details>
|
||||||
- Not all providers guarantee full compatibility
|
<summary>🌐 Potentially Compatible Providers</summary>
|
||||||
- Performance may vary between providers
|
|
||||||
- Check individual provider's documentation
|
#### Flexible Provider Ecosystem
|
||||||
|
The integration is designed to be flexible and may work with other providers offering OpenAI-compatible APIs:
|
||||||
|
- Groq
|
||||||
|
- Together AI
|
||||||
|
- Perplexity AI
|
||||||
|
- Mistral AI
|
||||||
|
- Google AI
|
||||||
|
- Local AI servers (like Ollama)
|
||||||
|
- Custom OpenAI-compatible endpoints
|
||||||
|
|
||||||
|
#### 🚨 Compatibility Notes
|
||||||
|
- Not all providers guarantee full compatibility
|
||||||
|
- Performance may vary between providers
|
||||||
|
- Check individual provider's documentation
|
||||||
- Ensure your API key has sufficient credits/quota
|
- Ensure your API key has sufficient credits/quota
|
||||||
|
|
||||||
#### Provider Compatibility Requirements
|
#### 🔍 Provider Compatibility Requirements
|
||||||
To be compatible, a provider should support:
|
To be compatible, a provider should support:
|
||||||
- OpenAI-like REST API structure
|
- OpenAI-like REST API structure
|
||||||
- JSON request/response format
|
- JSON request/response format
|
||||||
- Standard authentication method
|
- Standard authentication method
|
||||||
- Similar model parameter handling
|
- Similar model parameter handling
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
## ⚡ Installation
|
## ⚡ Installation
|
||||||
|
|
||||||
### HACS Installation (Recommended)
|
### HACS Installation (Recommended)
|
||||||
@@ -142,7 +178,8 @@ To be compatible, a provider should support:
|
|||||||
3. Search for "HA Text AI"
|
3. Search for "HA Text AI"
|
||||||
4. Follow the configuration steps
|
4. Follow the configuration steps
|
||||||
|
|
||||||
### Via YAML
|
<details>
|
||||||
|
<summary>📦 Via YAML (Advanced)</summary>
|
||||||
|
|
||||||
### Platform Configuration (Global Settings)
|
### Platform Configuration (Global Settings)
|
||||||
|
|
||||||
@@ -186,6 +223,8 @@ sensor:
|
|||||||
| `request_interval` | Float | ❌ | 1.0 | Delay between API requests |
|
| `request_interval` | Float | ❌ | 1.0 | Delay between API requests |
|
||||||
| `api_endpoint` | URL | ⚠️ | Provider default | Custom API endpoint |
|
| `api_endpoint` | URL | ⚠️ | Provider default | Custom API endpoint |
|
||||||
| `system_prompt` | String | ❌ | - | Default context for AI interactions |
|
| `system_prompt` | String | ❌ | - | Default context for AI interactions |
|
||||||
|
| `max_history_size` | Integer | ❌ | 100 | Maximum number of conversation entries to store |
|
||||||
|
| `history_file_size` | Integer | ⚠️ | 1 | Maximum history file size in MB |
|
||||||
|
|
||||||
#### Sensor Configuration
|
#### Sensor Configuration
|
||||||
|
|
||||||
@@ -198,6 +237,8 @@ sensor:
|
|||||||
| `temperature` | Float | ❌ | Platform setting | Override global temperature |
|
| `temperature` | Float | ❌ | Platform setting | Override global temperature |
|
||||||
| `max_tokens` | Integer | ❌ | Platform setting | Override global max tokens |
|
| `max_tokens` | Integer | ❌ | Platform setting | Override global max tokens |
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
## 🛠️ Available Services
|
## 🛠️ Available Services
|
||||||
|
|
||||||
### ask_question
|
### ask_question
|
||||||
@@ -210,12 +251,14 @@ data:
|
|||||||
max_tokens: 500 # optional
|
max_tokens: 500 # optional
|
||||||
context_messages: 10 #optional, number of previous messages to include in context, default: 5
|
context_messages: 10 #optional, number of previous messages to include in context, default: 5
|
||||||
system_prompt: "You are a sleep optimization expert" # optional
|
system_prompt: "You are a sleep optimization expert" # optional
|
||||||
|
instance: sensor.ha_text_ai_gpt
|
||||||
```
|
```
|
||||||
|
|
||||||
### set_system_prompt
|
### set_system_prompt
|
||||||
```yaml
|
```yaml
|
||||||
service: ha_text_ai.set_system_prompt
|
service: ha_text_ai.set_system_prompt
|
||||||
data:
|
data:
|
||||||
|
instance: sensor.ha_text_ai_gpt
|
||||||
prompt: |
|
prompt: |
|
||||||
You are a home automation expert focused on:
|
You are a home automation expert focused on:
|
||||||
1. Energy efficiency
|
1. Energy efficiency
|
||||||
@@ -243,7 +286,7 @@ data:
|
|||||||
- Only lowercase letters (a-z)
|
- Only lowercase letters (a-z)
|
||||||
- Numbers (0-9)
|
- Numbers (0-9)
|
||||||
- Underscore (_)
|
- Underscore (_)
|
||||||
- Maximum length: 50 characters (including `ha_text_ai_` prefix (14 characters)
|
- Maximum length: 50 characters (including `ha_text_ai_`)
|
||||||
|
|
||||||
#### Sensor Name Structure
|
#### Sensor Name Structure
|
||||||
```yaml
|
```yaml
|
||||||
@@ -254,7 +297,7 @@ sensor.ha_text_ai_YOUR_UNIQUE_SUFFIX
|
|||||||
# Examples:
|
# Examples:
|
||||||
sensor.ha_text_ai_gpt # GPT-based sensor
|
sensor.ha_text_ai_gpt # GPT-based sensor
|
||||||
sensor.ha_text_ai_claude # Claude-based sensor
|
sensor.ha_text_ai_claude # Claude-based sensor
|
||||||
sensor.ha_text_ai_gpt # Custom suffix
|
sensor.ha_text_ai_abc # Custom suffix
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Response Retrieval
|
#### Response Retrieval
|
||||||
@@ -271,6 +314,7 @@ automation:
|
|||||||
- service: ha_text_ai.ask_question
|
- service: ha_text_ai.ask_question
|
||||||
data:
|
data:
|
||||||
question: "Home automation advice"
|
question: "Home automation advice"
|
||||||
|
instance: sensor.ha_text_ai_gpt
|
||||||
- service: notify.mobile
|
- service: notify.mobile
|
||||||
data:
|
data:
|
||||||
message: >
|
message: >
|
||||||
@@ -287,6 +331,16 @@ automation:
|
|||||||
|
|
||||||
### 🔍 HA Text AI Sensor Attributes
|
### 🔍 HA Text AI Sensor Attributes
|
||||||
|
|
||||||
|
- 🤖 **Model and Provider Information**: Tracking current AI model and service provider
|
||||||
|
- 🚦 **System Status**: Real-time API and processing readiness
|
||||||
|
- 📊 **Performance Metrics**: Request success rates and response times
|
||||||
|
- 💬 **Conversation Tracking**: Token usage and interaction history are estimated using a heuristic method based on word count and specific word characteristics, which may differ from actual token usage.
|
||||||
|
- 🕒 **Last Interaction Details**: Recent query and response tracking
|
||||||
|
- ❤️ **System Health**: Error monitoring and service uptime
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>📦 Detailed Sensor Attributes</summary>
|
||||||
|
|
||||||
#### Model and Provider Information
|
#### Model and Provider Information
|
||||||
```yaml
|
```yaml
|
||||||
# Name of the AI model currently in use (e.g., latest version of GPT)
|
# Name of the AI model currently in use (e.g., latest version of GPT)
|
||||||
@@ -342,6 +396,12 @@ automation:
|
|||||||
|
|
||||||
# Tokens used in the AI's generated responses
|
# Tokens used in the AI's generated responses
|
||||||
{{ state_attr('sensor.ha_text_ai_gpt', 'Completion tokens') }} # 0
|
{{ state_attr('sensor.ha_text_ai_gpt', 'Completion tokens') }} # 0
|
||||||
|
|
||||||
|
# Number of entries in current history file
|
||||||
|
{{ state_attr('sensor.ha_text_ai_gpt', 'History size') }} # 0
|
||||||
|
|
||||||
|
# Last few conversation entries (limited to 3 for performance)
|
||||||
|
{{ state_attr('sensor.ha_text_ai_gpt', 'conversation_history') }} # [...]
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Last Interaction Details
|
#### Last Interaction Details
|
||||||
@@ -368,11 +428,19 @@ automation:
|
|||||||
{{ state_attr('sensor.ha_text_ai_gpt', 'Uptime') }} # 547,58
|
{{ state_attr('sensor.ha_text_ai_gpt', 'Uptime') }} # 547,58
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### History Storage
|
||||||
|
Conversation history stored in `.storage/ha_text_ai_history/` directory:
|
||||||
|
- Each instance has its own history file (JSON)
|
||||||
|
- Files are automatically rotated when size limit is reached
|
||||||
|
- Archived history files are timestamped
|
||||||
|
- Default maximum file size: 1MB
|
||||||
|
|
||||||
### 💡 Pro Tips
|
### 💡 Pro Tips
|
||||||
- Always check attribute existence
|
- Always check attribute existence
|
||||||
- Use these attributes for monitoring and automation
|
- Use these attributes for monitoring and automation
|
||||||
- Some values might be 0 or empty initially
|
- Some values might be 0 or empty initially
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
## 📘 FAQ
|
## 📘 FAQ
|
||||||
|
|
||||||
@@ -400,6 +468,15 @@ A: Yes, your data is secure. The system operates entirely on your local machine,
|
|||||||
**Q: How do context messages work?**
|
**Q: How do context messages work?**
|
||||||
A: Context messages allow the AI to remember and reference previous conversation history. By default, 5 previous messages are included, but you can customize this from 1 to 20 messages to control the conversation depth and token usage.
|
A: Context messages allow the AI to remember and reference previous conversation history. By default, 5 previous messages are included, but you can customize this from 1 to 20 messages to control the conversation depth and token usage.
|
||||||
|
|
||||||
|
**Q: Where is conversation history stored?**
|
||||||
|
A: History is stored in files under the `.storage/ha_text_ai_history/` directory, with automatic rotation and size management.
|
||||||
|
|
||||||
|
**Q: Can I access old conversation history?**
|
||||||
|
A: Yes, archived history files are stored with timestamps and can be accessed manually if needed.
|
||||||
|
|
||||||
|
**Q: How much history is kept?**
|
||||||
|
A: By default, up to 100 conversations are stored, but this can be configured. Files are automatically rotated when they reach 1MB.
|
||||||
|
|
||||||
## 🤝 Contributing
|
## 🤝 Contributing
|
||||||
|
|
||||||
Contributions welcome! Please read our [Contributing Guide](CONTRIBUTING.md).
|
Contributions welcome! Please read our [Contributing Guide](CONTRIBUTING.md).
|
||||||
@@ -410,9 +487,23 @@ Contributions welcome! Please read our [Contributing Guide](CONTRIBUTING.md).
|
|||||||
4. Push branch (`git push origin feature/Enhancement`)
|
4. Push branch (`git push origin feature/Enhancement`)
|
||||||
5. Open Pull Request
|
5. Open Pull Request
|
||||||
|
|
||||||
|
## Legal Disclaimer and Limitation of Liability
|
||||||
|
|
||||||
|
### Software Disclaimer
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
## 📝 License
|
## 📝 License
|
||||||
|
|
||||||
MIT License - see [LICENSE](LICENSE) for details.
|
Author: SMKRV
|
||||||
|
[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/) - see [LICENSE](LICENSE) for details.
|
||||||
|
|
||||||
## 💡 Support the Project
|
## 💡 Support the Project
|
||||||
|
|
||||||
@@ -432,9 +523,11 @@ If you want to say thanks financially, you can send a small token of appreciatio
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
<div align="center"><img src="https://github.com/smkrv/ha-text-ai/blob/2aaf3405759eb2d97624834594e24ace896131df/assets/images/icons/footer_icon.png" alt="HA Text AI" style="width: 128px; height: auto;"/></div>
|
||||||
<div align="center">
|
<div align="center">
|
||||||
|
|
||||||
Made with ❤️ and Claude 3.5 Sonnet for the Home Assistant Community
|
Made with ❤️ for the Home Assistant Community,
|
||||||
|
utilizing Claude 3.5 Sonnet, Gemini Pro 1.5, and Qwen 2.5 Coder 32B Instruct.
|
||||||
|
|
||||||
[Report Bug](https://github.com/smkrv/ha-text-ai/issues) · [Request Feature](https://github.com/smkrv/ha-text-ai/issues)
|
[Report Bug](https://github.com/smkrv/ha-text-ai/issues) · [Request Feature](https://github.com/smkrv/ha-text-ai/issues)
|
||||||
|
|
||||||
|
|||||||
|
After Width: | Height: | Size: 102 KiB |
|
Before Width: | Height: | Size: 618 KiB After Width: | Height: | Size: 618 KiB |
|
Before Width: | Height: | Size: 923 KiB After Width: | Height: | Size: 923 KiB |
|
After Width: | Height: | Size: 339 KiB |
|
After Width: | Height: | Size: 1.0 MiB |
@@ -1,11 +1,19 @@
|
|||||||
"""The HA Text AI integration."""
|
"""
|
||||||
|
The HA Text AI integration.
|
||||||
|
|
||||||
|
@license: CC BY-NC-SA 4.0 International
|
||||||
|
@author: SMKRV
|
||||||
|
@github: https://github.com/smkrv/ha-text-ai
|
||||||
|
@source: https://github.com/smkrv/ha-text-ai
|
||||||
|
"""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
|
import hashlib
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from typing import Any, Dict
|
from typing import Any, Dict, TypeVar
|
||||||
|
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
from async_timeout import timeout
|
from async_timeout import timeout
|
||||||
@@ -45,11 +53,13 @@ from .const import (
|
|||||||
SERVICE_SET_SYSTEM_PROMPT,
|
SERVICE_SET_SYSTEM_PROMPT,
|
||||||
DEFAULT_MAX_HISTORY,
|
DEFAULT_MAX_HISTORY,
|
||||||
CONF_MAX_HISTORY_SIZE,
|
CONF_MAX_HISTORY_SIZE,
|
||||||
|
ICONS_SUBDOMAIN,
|
||||||
)
|
)
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
CONFIG_SCHEMA = cv.config_entry_only_config_schema(DOMAIN)
|
CONFIG_SCHEMA = cv.config_entry_only_config_schema(DOMAIN)
|
||||||
|
ConfigType = TypeVar("ConfigType", bound=Dict[str, Any])
|
||||||
|
|
||||||
SERVICE_SCHEMA_ASK_QUESTION = vol.Schema({
|
SERVICE_SCHEMA_ASK_QUESTION = vol.Schema({
|
||||||
vol.Required("instance"): cv.string,
|
vol.Required("instance"): cv.string,
|
||||||
@@ -83,19 +93,18 @@ def get_coordinator_by_instance(hass: HomeAssistant, instance: str) -> HATextAIC
|
|||||||
|
|
||||||
raise HomeAssistantError(f"Instance {instance} not found")
|
raise HomeAssistantError(f"Instance {instance} not found")
|
||||||
|
|
||||||
async def async_setup(hass: HomeAssistant, config: Dict[str, Any]) -> bool:
|
def get_file_hash(file_path: str) -> str:
|
||||||
"""Set up the HA Text AI component."""
|
"""Calculate SHA256 hash of file."""
|
||||||
hass.data.setdefault(DOMAIN, {})
|
sha256_hash = hashlib.sha256()
|
||||||
|
with open(file_path, "rb") as f:
|
||||||
|
for byte_block in iter(lambda: f.read(4096), b""):
|
||||||
|
sha256_hash.update(byte_block)
|
||||||
|
return sha256_hash.hexdigest()
|
||||||
|
|
||||||
try:
|
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
||||||
source = os.path.join(os.path.dirname(__file__), 'icons', 'icon.svg')
|
"""Set up the Home Assistant Text AI component."""
|
||||||
dest_dir = os.path.join(hass.config.path('www'), 'icons')
|
# Initialize domain data storage
|
||||||
os.makedirs(dest_dir, exist_ok=True)
|
hass.data.setdefault(DOMAIN, {})
|
||||||
dest = os.path.join(dest_dir, 'icon.png')
|
|
||||||
if not os.path.exists(dest):
|
|
||||||
shutil.copyfile(source, dest)
|
|
||||||
except Exception as ex:
|
|
||||||
_LOGGER.warning("Failed to copy custom icon: %s", str(ex))
|
|
||||||
|
|
||||||
async def async_ask_question(call: ServiceCall) -> None:
|
async def async_ask_question(call: ServiceCall) -> None:
|
||||||
"""Handle ask_question service."""
|
"""Handle ask_question service."""
|
||||||
@@ -143,6 +152,7 @@ async def async_setup(hass: HomeAssistant, config: Dict[str, Any]) -> bool:
|
|||||||
_LOGGER.error("Error setting system prompt: %s", str(err))
|
_LOGGER.error("Error setting system prompt: %s", str(err))
|
||||||
raise HomeAssistantError(f"Failed to set system prompt: {str(err)}")
|
raise HomeAssistantError(f"Failed to set system prompt: {str(err)}")
|
||||||
|
|
||||||
|
# Register services
|
||||||
hass.services.async_register(
|
hass.services.async_register(
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
SERVICE_ASK_QUESTION,
|
SERVICE_ASK_QUESTION,
|
||||||
@@ -171,6 +181,53 @@ async def async_setup(hass: HomeAssistant, config: Dict[str, Any]) -> bool:
|
|||||||
schema=SERVICE_SCHEMA_SET_SYSTEM_PROMPT
|
schema=SERVICE_SCHEMA_SET_SYSTEM_PROMPT
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Handle icons
|
||||||
|
try:
|
||||||
|
source_icon_path = os.path.join(
|
||||||
|
os.path.dirname(__file__),
|
||||||
|
ICONS_SUBDOMAIN,
|
||||||
|
'icon@2x.png'
|
||||||
|
)
|
||||||
|
|
||||||
|
destination_directory = os.path.join(
|
||||||
|
hass.config.path('www'),
|
||||||
|
DOMAIN,
|
||||||
|
ICONS_SUBDOMAIN
|
||||||
|
)
|
||||||
|
|
||||||
|
destination_icon_path = os.path.join(
|
||||||
|
destination_directory,
|
||||||
|
'icon.png'
|
||||||
|
)
|
||||||
|
|
||||||
|
if not os.path.exists(source_icon_path):
|
||||||
|
_LOGGER.error("Source icon not found: %s", source_icon_path)
|
||||||
|
return True
|
||||||
|
|
||||||
|
def create_directory():
|
||||||
|
os.makedirs(destination_directory, exist_ok=True)
|
||||||
|
|
||||||
|
await hass.async_add_executor_job(create_directory)
|
||||||
|
|
||||||
|
should_copy = True
|
||||||
|
|
||||||
|
if os.path.exists(destination_icon_path):
|
||||||
|
source_hash = await hass.async_add_executor_job(get_file_hash, source_icon_path)
|
||||||
|
dest_hash = await hass.async_add_executor_job(get_file_hash, destination_icon_path)
|
||||||
|
should_copy = source_hash != dest_hash
|
||||||
|
|
||||||
|
if should_copy:
|
||||||
|
def copy_file():
|
||||||
|
shutil.copyfile(source_icon_path, destination_icon_path)
|
||||||
|
|
||||||
|
await hass.async_add_executor_job(copy_file)
|
||||||
|
_LOGGER.debug("Icon updated: %s", destination_icon_path)
|
||||||
|
|
||||||
|
except PermissionError as e:
|
||||||
|
_LOGGER.error("Permission denied when managing icons: %s", str(e))
|
||||||
|
except Exception as e:
|
||||||
|
_LOGGER.error("Failed to manage icons: %s", str(e))
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
async def async_check_api(session, endpoint: str, headers: dict, provider: str) -> bool:
|
async def async_check_api(session, endpoint: str, headers: dict, provider: str) -> bool:
|
||||||
|
|||||||
@@ -1,4 +1,11 @@
|
|||||||
"""API Client for HA Text AI."""
|
"""
|
||||||
|
API Client for HA Text AI.
|
||||||
|
|
||||||
|
@license: CC BY-NC-SA 4.0 International
|
||||||
|
@author: SMKRV
|
||||||
|
@github: https://github.com/smkrv/ha-text-ai
|
||||||
|
@source: https://github.com/smkrv/ha-text-ai
|
||||||
|
"""
|
||||||
import logging
|
import logging
|
||||||
import asyncio
|
import asyncio
|
||||||
from typing import Any, Dict, List, Optional
|
from typing import Any, Dict, List, Optional
|
||||||
|
|||||||
@@ -1,4 +1,11 @@
|
|||||||
"""Config flow for HA text AI integration."""
|
"""
|
||||||
|
Config flow for HA text AI integration.
|
||||||
|
|
||||||
|
@license: CC BY-NC-SA 4.0 International
|
||||||
|
@author: SMKRV
|
||||||
|
@github: https://github.com/smkrv/ha-text-ai
|
||||||
|
@source: https://github.com/smkrv/ha-text-ai
|
||||||
|
"""
|
||||||
import logging
|
import logging
|
||||||
from typing import Any, Dict, Optional
|
from typing import Any, Dict, Optional
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,11 @@
|
|||||||
"""Constants for the HA text AI integration."""
|
"""
|
||||||
|
Constants for the HA text AI integration.
|
||||||
|
|
||||||
|
@license: CC BY-NC-SA 4.0 International
|
||||||
|
@author: SMKRV
|
||||||
|
@github: https://github.com/smkrv/ha-text-ai
|
||||||
|
@source: https://github.com/smkrv/ha-text-ai
|
||||||
|
"""
|
||||||
from typing import Final
|
from typing import Final
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
from homeassistant.const import Platform, CONF_API_KEY, CONF_NAME
|
from homeassistant.const import Platform, CONF_API_KEY, CONF_NAME
|
||||||
@@ -33,6 +40,11 @@ CONF_MAX_HISTORY_SIZE: Final = "max_history_size" # Correct constant name
|
|||||||
CONF_IS_ANTHROPIC: Final = "is_anthropic"
|
CONF_IS_ANTHROPIC: Final = "is_anthropic"
|
||||||
CONF_CONTEXT_MESSAGES: Final = "context_messages"
|
CONF_CONTEXT_MESSAGES: Final = "context_messages"
|
||||||
|
|
||||||
|
ABSOLUTE_MAX_HISTORY_SIZE = 500
|
||||||
|
MAX_ATTRIBUTE_SIZE = 4 * 1024
|
||||||
|
MAX_HISTORY_FILE_SIZE = 1 * 1024 * 1024
|
||||||
|
ICONS_SUBDOMAIN = "icons"
|
||||||
|
|
||||||
# Default values
|
# Default values
|
||||||
DEFAULT_MODEL: Final = "gpt-4o-mini"
|
DEFAULT_MODEL: Final = "gpt-4o-mini"
|
||||||
DEFAULT_TEMPERATURE: Final = 0.1
|
DEFAULT_TEMPERATURE: Final = 0.1
|
||||||
|
|||||||
|
After Width: | Height: | Size: 121 KiB |
|
After Width: | Height: | Size: 351 KiB |
|
After Width: | Height: | Size: 87 KiB |
|
After Width: | Height: | Size: 257 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 117 KiB |
|
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 325 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 86 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 259 KiB |
@@ -13,16 +13,16 @@
|
|||||||
"loggers": ["custom_components.ha_text_ai"],
|
"loggers": ["custom_components.ha_text_ai"],
|
||||||
"mqtt": [],
|
"mqtt": [],
|
||||||
"quality_scale": "silver",
|
"quality_scale": "silver",
|
||||||
"requirements": [
|
"requirements": [
|
||||||
"openai>=1.12.0",
|
"openai>=1.12.0",
|
||||||
"anthropic>=0.8.0",
|
"anthropic>=0.8.0",
|
||||||
"aiohttp>=3.8.0",
|
"aiohttp>=3.8.0",
|
||||||
"async-timeout>=4.0.0",
|
"async-timeout>=4.0.0",
|
||||||
"certifi>=2024.2.2"
|
"certifi>=2024.2.2"
|
||||||
],
|
],
|
||||||
"single_config_entry": false,
|
"single_config_entry": false,
|
||||||
"ssdp": [],
|
"ssdp": [],
|
||||||
"usb": [],
|
"usb": [],
|
||||||
"version": "2.0.3-beta",
|
"version": "2.0.8",
|
||||||
"zeroconf": []
|
"zeroconf": []
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,11 @@
|
|||||||
"""Sensor platform for HA Text AI."""
|
"""
|
||||||
|
Sensor platform for HA Text AI.
|
||||||
|
|
||||||
|
@license: CC BY-NC-SA 4.0 International
|
||||||
|
@author: SMKRV
|
||||||
|
@github: https://github.com/smkrv/ha-text-ai
|
||||||
|
@source: https://github.com/smkrv/ha-text-ai
|
||||||
|
"""
|
||||||
import logging
|
import logging
|
||||||
import math
|
import math
|
||||||
from typing import Any, Dict
|
from typing import Any, Dict
|
||||||
@@ -60,6 +67,7 @@ from .const import (
|
|||||||
ENTITY_ICON_PROCESSING,
|
ENTITY_ICON_PROCESSING,
|
||||||
DEFAULT_NAME_PREFIX,
|
DEFAULT_NAME_PREFIX,
|
||||||
CONF_MAX_HISTORY_SIZE,
|
CONF_MAX_HISTORY_SIZE,
|
||||||
|
MAX_ATTRIBUTE_SIZE,
|
||||||
)
|
)
|
||||||
|
|
||||||
from .coordinator import HATextAICoordinator
|
from .coordinator import HATextAICoordinator
|
||||||
@@ -171,12 +179,29 @@ class HATextAISensor(CoordinatorEntity, SensorEntity):
|
|||||||
|
|
||||||
def _sanitize_attributes(self, attributes: Dict[str, Any]) -> Dict[str, Any]:
|
def _sanitize_attributes(self, attributes: Dict[str, Any]) -> Dict[str, Any]:
|
||||||
"""Sanitize all attributes for JSON serialization."""
|
"""Sanitize all attributes for JSON serialization."""
|
||||||
return {
|
sanitized = {
|
||||||
key: self._sanitize_value(value)
|
key: self._sanitize_value(value)
|
||||||
for key, value in attributes.items()
|
for key, value in attributes.items()
|
||||||
if value is not None
|
if value is not None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Log metrics for debugging
|
||||||
|
metrics_keys = [
|
||||||
|
METRIC_TOTAL_TOKENS,
|
||||||
|
METRIC_PROMPT_TOKENS,
|
||||||
|
METRIC_COMPLETION_TOKENS,
|
||||||
|
METRIC_SUCCESSFUL_REQUESTS,
|
||||||
|
METRIC_FAILED_REQUESTS,
|
||||||
|
METRIC_AVERAGE_LATENCY,
|
||||||
|
METRIC_MAX_LATENCY,
|
||||||
|
METRIC_MIN_LATENCY,
|
||||||
|
]
|
||||||
|
|
||||||
|
metrics_values = {k: sanitized.get(k) for k in metrics_keys if k in sanitized}
|
||||||
|
_LOGGER.debug(f"Metrics for {self.entity_id}: {metrics_values}")
|
||||||
|
|
||||||
|
return sanitized
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def native_value(self) -> StateType:
|
def native_value(self) -> StateType:
|
||||||
"""Return the native value of the sensor."""
|
"""Return the native value of the sensor."""
|
||||||
@@ -205,68 +230,65 @@ class HATextAISensor(CoordinatorEntity, SensorEntity):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
data = self.coordinator.data
|
data = self.coordinator.data
|
||||||
|
metrics = data.get("metrics", {})
|
||||||
|
|
||||||
|
# Base attributes
|
||||||
attributes = {
|
attributes = {
|
||||||
ATTR_MODEL: self._config_entry.data.get(CONF_MODEL, "Unknown"),
|
ATTR_MODEL: self._config_entry.data.get(CONF_MODEL, "Unknown"),
|
||||||
ATTR_API_PROVIDER: self._config_entry.data.get(
|
ATTR_API_PROVIDER: self._config_entry.data.get(CONF_API_PROVIDER, "Unknown"),
|
||||||
CONF_API_PROVIDER, "Unknown"
|
|
||||||
),
|
|
||||||
ATTR_API_STATUS: self._current_state,
|
ATTR_API_STATUS: self._current_state,
|
||||||
ATTR_TOTAL_ERRORS: self._error_count,
|
ATTR_TOTAL_ERRORS: metrics.get("total_errors", 0),
|
||||||
ATTR_LAST_ERROR: self._last_error,
|
|
||||||
"instance_name": self._instance_name,
|
"instance_name": self._instance_name,
|
||||||
"normalized_name": self._normalized_name,
|
"normalized_name": self._normalized_name,
|
||||||
ATTR_SYSTEM_PROMPT: data.get("system_prompt"),
|
ATTR_SYSTEM_PROMPT: (data.get("system_prompt", "")[:MAX_ATTRIBUTE_SIZE]
|
||||||
|
if data.get("system_prompt") else None),
|
||||||
ATTR_IS_PROCESSING: data.get("is_processing", False),
|
ATTR_IS_PROCESSING: data.get("is_processing", False),
|
||||||
ATTR_IS_RATE_LIMITED: data.get("is_rate_limited", False),
|
ATTR_IS_RATE_LIMITED: data.get("is_rate_limited", False),
|
||||||
ATTR_IS_MAINTENANCE: data.get("is_maintenance", False),
|
ATTR_IS_MAINTENANCE: data.get("is_maintenance", False),
|
||||||
ATTR_ENDPOINT_STATUS: data.get("endpoint_status", "unknown"),
|
ATTR_ENDPOINT_STATUS: data.get("endpoint_status", "unknown"),
|
||||||
ATTR_UPTIME: data.get("uptime", 0),
|
ATTR_UPTIME: round(data.get("uptime", 0), 2),
|
||||||
ATTR_HISTORY_SIZE: data.get("history_size", 0),
|
ATTR_HISTORY_SIZE: data.get("history_size", 0),
|
||||||
ATTR_CONVERSATION_HISTORY: data.get("conversation_history", []),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Add metrics
|
# History limit
|
||||||
metrics = data.get("metrics", {})
|
conversation_history = data.get("conversation_history", [])
|
||||||
if isinstance(metrics, dict):
|
if conversation_history:
|
||||||
self._metrics = metrics
|
limited_history = []
|
||||||
attributes.update(
|
for entry in conversation_history:
|
||||||
{
|
limited_entry = {
|
||||||
METRIC_TOTAL_TOKENS: metrics.get("total_tokens", 0),
|
"timestamp": entry["timestamp"],
|
||||||
METRIC_PROMPT_TOKENS: metrics.get("prompt_tokens", 0),
|
"question": entry["question"][:MAX_ATTRIBUTE_SIZE],
|
||||||
METRIC_COMPLETION_TOKENS: metrics.get("completion_tokens", 0),
|
"response": entry["response"][:MAX_ATTRIBUTE_SIZE]
|
||||||
METRIC_SUCCESSFUL_REQUESTS: metrics.get(
|
|
||||||
"successful_requests", 0
|
|
||||||
),
|
|
||||||
METRIC_FAILED_REQUESTS: metrics.get("failed_requests", 0),
|
|
||||||
METRIC_AVERAGE_LATENCY: metrics.get("average_latency", 0),
|
|
||||||
METRIC_MAX_LATENCY: metrics.get("max_latency", 0),
|
|
||||||
METRIC_MIN_LATENCY: metrics.get("min_latency", float("inf")),
|
|
||||||
}
|
}
|
||||||
)
|
limited_history.append(limited_entry)
|
||||||
|
attributes[ATTR_CONVERSATION_HISTORY] = limited_history
|
||||||
|
|
||||||
# Add last response
|
# Metrics
|
||||||
|
if isinstance(metrics, dict):
|
||||||
|
attributes.update({
|
||||||
|
METRIC_TOTAL_TOKENS: metrics.get("total_tokens", 0),
|
||||||
|
METRIC_PROMPT_TOKENS: metrics.get("prompt_tokens", 0),
|
||||||
|
METRIC_COMPLETION_TOKENS: metrics.get("completion_tokens", 0),
|
||||||
|
METRIC_SUCCESSFUL_REQUESTS: metrics.get("successful_requests", 0),
|
||||||
|
METRIC_FAILED_REQUESTS: metrics.get("failed_requests", 0),
|
||||||
|
METRIC_AVERAGE_LATENCY: round(metrics.get("average_latency", 0), 2),
|
||||||
|
METRIC_MAX_LATENCY: round(metrics.get("max_latency", 0), 2),
|
||||||
|
METRIC_MIN_LATENCY: (metrics.get("min_latency")
|
||||||
|
if metrics.get("min_latency") != float("inf")
|
||||||
|
else None),
|
||||||
|
})
|
||||||
|
|
||||||
|
# Last response handling
|
||||||
last_response = data.get("last_response", {})
|
last_response = data.get("last_response", {})
|
||||||
if isinstance(last_response, dict):
|
if isinstance(last_response, dict):
|
||||||
self._last_response = last_response
|
attributes.update({
|
||||||
attributes.update(
|
ATTR_RESPONSE: last_response.get("response", "")[:MAX_ATTRIBUTE_SIZE],
|
||||||
{
|
ATTR_QUESTION: last_response.get("question", "")[:MAX_ATTRIBUTE_SIZE],
|
||||||
ATTR_RESPONSE: last_response.get("response", ""),
|
"last_model": last_response.get("model", ""),
|
||||||
ATTR_QUESTION: last_response.get("question", ""),
|
"last_timestamp": last_response.get("timestamp", ""),
|
||||||
"last_model": last_response.get("model", ""),
|
"last_error": (last_response.get("error", "")[:MAX_ATTRIBUTE_SIZE]
|
||||||
"last_timestamp": last_response.get("timestamp", ""),
|
if last_response.get("error") else None),
|
||||||
"last_error": last_response.get("error"),
|
})
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
# Add performance metrics if available
|
|
||||||
if ATTR_PERFORMANCE_METRICS in data:
|
|
||||||
attributes[ATTR_PERFORMANCE_METRICS] = data[
|
|
||||||
ATTR_PERFORMANCE_METRICS
|
|
||||||
]
|
|
||||||
|
|
||||||
# Add API version if available
|
|
||||||
if ATTR_API_VERSION in data:
|
|
||||||
attributes[ATTR_API_VERSION] = data[ATTR_API_VERSION]
|
|
||||||
|
|
||||||
return self._sanitize_attributes(attributes)
|
return self._sanitize_attributes(attributes)
|
||||||
|
|
||||||
@@ -292,6 +314,12 @@ class HATextAISensor(CoordinatorEntity, SensorEntity):
|
|||||||
|
|
||||||
self._is_processing = data.get("is_processing", False)
|
self._is_processing = data.get("is_processing", False)
|
||||||
|
|
||||||
|
# Update metrics
|
||||||
|
metrics = data.get("metrics", {})
|
||||||
|
if isinstance(metrics, dict):
|
||||||
|
self._metrics.update(metrics)
|
||||||
|
_LOGGER.debug(f"Updated metrics for {self.entity_id}: {self._metrics}")
|
||||||
|
|
||||||
# Update conversation history and system prompt
|
# Update conversation history and system prompt
|
||||||
self._conversation_history = data.get("conversation_history", [])
|
self._conversation_history = data.get("conversation_history", [])
|
||||||
self._system_prompt = data.get("system_prompt")
|
self._system_prompt = data.get("system_prompt")
|
||||||
|
|||||||
@@ -2,71 +2,101 @@
|
|||||||
"config": {
|
"config": {
|
||||||
"step": {
|
"step": {
|
||||||
"provider": {
|
"provider": {
|
||||||
"title": "KI-Anbieter auswählen",
|
"title": "Wählen Sie AI-Anbieter",
|
||||||
"description": "Wählen Sie den KI-Dienstanbieter für diese Instanz aus.",
|
"description": "Wählen Sie, welchen AI-Dienstanbieter Sie für diese Instanz verwenden möchten.",
|
||||||
"data": {
|
"data": {
|
||||||
"api_provider": "API-Anbieter",
|
"api_provider": "API-Anbieter",
|
||||||
"context_messages": "Anzahl der zu behaltenden Kontextnachrichten (1-20)"
|
"context_messages": "Anzahl der zu behaltenden Kontextnachrichten (1-20)",
|
||||||
|
"max_history_size": "Maximale Größe des Gesprächsverlaufs (1-100)"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"provider": {
|
||||||
|
"title": "Anbieter-Einstellungen",
|
||||||
|
"description": "Geben Sie die Verbindungsdetails für Ihren gewählten AI-Anbieter an.",
|
||||||
|
"data": {
|
||||||
|
"name": "Instanzname (z. B. 'GPT Assistant', 'Claude Helper')",
|
||||||
|
"api_key": "API-Schlüssel zur Authentifizierung",
|
||||||
|
"model": "Zu verwendendes AI-Modell",
|
||||||
|
"api_endpoint": "Benutzerdefinierte API-Endpunkt-URL (optional)",
|
||||||
|
"temperature": "Kreativität der Antwort (0-2, niedriger = fokussierter)",
|
||||||
|
"max_tokens": "Maximale Länge der Antwort (1-4096 Token)",
|
||||||
|
"request_interval": "Minimale Zeit zwischen Anfragen (0,1-60 Sekunden)",
|
||||||
|
"context_messages": "Anzahl der zu behaltenden Kontextnachrichten (1-20)",
|
||||||
|
"max_history_size": "Maximale Größe des Gesprächsverlaufs (1-100)"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"user": {
|
"user": {
|
||||||
"title": "HA Text AI-Instanz konfigurieren",
|
"title": "HA Text AI Instanz konfigurieren",
|
||||||
"description": "Richten Sie eine neue KI-Assistenteninstanz mit Ihrem ausgewählten Anbieter ein.",
|
"description": "Richten Sie eine neue AI-Assistenteninstanz mit Ihrem ausgewählten Anbieter ein.",
|
||||||
"data": {
|
"data": {
|
||||||
"name": "Instanzname (z. B. 'GPT-Assistent', 'Claude-Helfer')",
|
"name": "Instanzname (z. B. 'GPT Assistant', 'Claude Helper')",
|
||||||
"api_key": "API-Schlüssel zur Authentifizierung",
|
"api_key": "API-Schlüssel zur Authentifizierung",
|
||||||
"model": "Zu verwendendes KI-Modell",
|
"model": "Zu verwendendes AI-Modell",
|
||||||
"temperature": "Antwortkreativität (0-2, niedriger = fokussierter)",
|
"temperature": "Kreativität der Antwort (0-2, niedriger = fokussierter)",
|
||||||
"max_tokens": "Maximale Antwortlänge (1-4096 Token)",
|
"max_tokens": "Maximale Länge der Antwort (1-4096 Token)",
|
||||||
"api_endpoint": "Benutzerdefinierte API-Endpunkt-URL (optional)",
|
"api_endpoint": "Benutzerdefinierte API-Endpunkt-URL (optional)",
|
||||||
"api_provider": "API-Anbieter",
|
"api_provider": "API-Anbieter",
|
||||||
"request_interval": "Mindestzeit zwischen Anfragen (0,1-60 Sekunden)",
|
"request_interval": "Minimale Zeit zwischen Anfragen (0,1-60 Sekunden)",
|
||||||
"context_messages": "Anzahl der zu behaltenden Kontextnachrichten (1-20)",
|
"context_messages": "Anzahl der zu behaltenden Kontextnachrichten (1-20)",
|
||||||
"max_history_size": "Maximale Größe des Konversationsverlaufs (1-100)"
|
"max_history_size": "Maximale Größe des Gesprächsverlaufs (1-100)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"error": {
|
"error": {
|
||||||
|
"history_storage_error": "Fehler beim Initialisieren des Verlaufspeichers. Überprüfen Sie die Berechtigungen.",
|
||||||
|
"history_rotation_error": "Fehler beim Drehen der Verlaufsdatei.",
|
||||||
|
"history_file_access_error": "Zugriff auf das Verzeichnis für den Verlaufsspeicher nicht möglich.",
|
||||||
"name_exists": "Eine Instanz mit diesem Namen existiert bereits",
|
"name_exists": "Eine Instanz mit diesem Namen existiert bereits",
|
||||||
"invalid_name": "Ungültiger Instanzname",
|
"invalid_name": "Ungültiger Instanzname",
|
||||||
"invalid_auth": "Authentifizierung fehlgeschlagen - überprüfen Sie Ihren API-Schlüssel",
|
"invalid_auth": "Authentifizierung fehlgeschlagen - überprüfen Sie Ihren API-Schlüssel",
|
||||||
"invalid_api_key": "Ungültiger API-Schlüssel - überprüfen Sie Ihre Anmeldedaten",
|
"invalid_api_key": "Ungültiger API-Schlüssel - bitte überprüfen Sie Ihre Anmeldeinformationen",
|
||||||
"cannot_connect": "Verbindung zum API-Dienst fehlgeschlagen",
|
"cannot_connect": "Verbindung zum API-Dienst fehlgeschlagen",
|
||||||
"invalid_model": "Das ausgewählte Modell ist nicht verfügbar",
|
"invalid_model": "Ausgewähltes Modell ist nicht verfügbar",
|
||||||
"rate_limit": "Ratenlimit überschritten",
|
"rate_limit": "Rate-Limit überschritten",
|
||||||
"context_length": "Kontextlänge überschritten",
|
"context_length": "Kontextlänge überschritten",
|
||||||
"rate_limit_exceeded": "API-Ratenlimit überschritten",
|
"rate_limit_exceeded": "API-Rate-Limit überschritten",
|
||||||
"maintenance": "Dienst befindet sich in der Wartung",
|
"maintenance": "Dienst ist in Wartung",
|
||||||
"invalid_response": "Ungültige API-Antwort empfangen",
|
"invalid_response": "Ungültige API-Antwort erhalten",
|
||||||
"api_error": "Fehler im API-Dienst aufgetreten",
|
"api_error": "Ein Fehler im API-Dienst ist aufgetreten",
|
||||||
"timeout": "Anfrage ist abgelaufen",
|
"timeout": "Zeitüberschreitung bei der Anfrage",
|
||||||
"invalid_instance": "Ungültige Instanz angegeben",
|
"invalid_instance": "Ungültige Instanz angegeben",
|
||||||
"unknown": "Es ist ein unerwarteter Fehler aufgetreten",
|
"unknown": "Unerwarteter Fehler aufgetreten",
|
||||||
"empty": "Name darf nicht leer sein",
|
"empty": "Name darf nicht leer sein",
|
||||||
"invalid_characters": "Name darf nur Buchstaben, Zahlen, Leerzeichen, Unterstriche und Bindestriche enthalten",
|
"invalid_characters": "Name darf nur Buchstaben, Zahlen, Leerzeichen, Unterstriche und Bindestriche enthalten",
|
||||||
"name_too_long": "Name darf maximal 50 Zeichen lang sein"
|
"name_too_long": "Name darf höchstens 50 Zeichen lang sein"
|
||||||
|
},
|
||||||
|
"abort": {
|
||||||
|
"already_configured": "Instanz bereits konfiguriert"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"options": {
|
"options": {
|
||||||
"step": {
|
"step": {
|
||||||
"init": {
|
"init": {
|
||||||
"title": "Instanzeinstellungen aktualisieren",
|
"title": "Instanzeinstellungen aktualisieren",
|
||||||
"description": "Ändern Sie die Einstellungen für diese KI-Assistenteninstanz.",
|
"description": "Ändern Sie die Einstellungen für diese AI-Assistenteninstanz.",
|
||||||
"data": {
|
"data": {
|
||||||
"model": "KI-Modell",
|
"model": "AI-Modell",
|
||||||
"temperature": "Antwortkreativität (0-2)",
|
"temperature": "Kreativität der Antwort (0-2)",
|
||||||
"max_tokens": "Maximale Antwortlänge (1-4096)",
|
"max_tokens": "Maximale Länge der Antwort (1-4096)",
|
||||||
"request_interval": "Mindestzeitraum zwischen Anfragen (0,1-60 Sekunden)",
|
"request_interval": "Minimale Anfrageintervall (0,1-60 Sekunden)",
|
||||||
"context_messages": "Anzahl der vorherigen Nachrichten, die im Kontext enthalten sein sollen (1-20)",
|
"context_messages": "Anzahl der vorherigen Nachrichten, die im Kontext enthalten sein sollen (1-20)",
|
||||||
"max_history_size": "Maximale Größe des Konversationsverlaufs (1-100)"
|
"max_history_size": "Maximale Größe des Gesprächsverlaufs (1-100)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"selector": {
|
||||||
|
"api_provider": {
|
||||||
|
"options": {
|
||||||
|
"openai": "OpenAI (kompatibel)",
|
||||||
|
"anthropic": "Anthropic (kompatibel)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"services": {
|
"services": {
|
||||||
"ask_question": {
|
"ask_question": {
|
||||||
"name": "Frage stellen (HA Text AI)",
|
"name": "Frage stellen (HA Text AI)",
|
||||||
"description": "Senden Sie eine Frage an das KI-Modell und erhalten Sie eine detaillierte Antwort. Die Antwort wird im Konversationsverlauf gespeichert und kann später abgerufen werden.",
|
"description": "Stellen Sie eine Frage an das AI-Modell und erhalten Sie eine detaillierte Antwort. Die Antwort wird im Gesprächsverlauf gespeichert und kann später abgerufen werden.",
|
||||||
"fields": {
|
"fields": {
|
||||||
"instance": {
|
"instance": {
|
||||||
"name": "Instanz",
|
"name": "Instanz",
|
||||||
@@ -74,43 +104,43 @@
|
|||||||
},
|
},
|
||||||
"question": {
|
"question": {
|
||||||
"name": "Frage",
|
"name": "Frage",
|
||||||
"description": "Ihre Frage oder Aufforderung an den KI-Assistenten"
|
"description": "Ihre Frage oder Aufforderung für den AI-Assistenten"
|
||||||
},
|
},
|
||||||
"context_messages": {
|
"context_messages": {
|
||||||
"name": "Kontextnachrichten",
|
"name": "Kontextnachrichten",
|
||||||
"description": "Anzahl der vorherigen Nachrichten, die im Kontext enthalten sein sollen (1-20)"
|
"description": "Anzahl der vorherigen Nachrichten, die im Kontext enthalten sein sollen (1-20)"
|
||||||
},
|
},
|
||||||
"system_prompt": {
|
"system_prompt": {
|
||||||
"name": "Systemprompt",
|
"name": "Systemaufforderung",
|
||||||
"description": "Optionaler Systemprompt, um den Kontext für diese spezielle Frage festzulegen"
|
"description": "Optionale Systemaufforderung zur Festlegung des Kontexts für diese spezifische Frage"
|
||||||
},
|
},
|
||||||
"model": {
|
"model": {
|
||||||
"name": "Modell",
|
"name": "Modell",
|
||||||
"description": "Wählen Sie das zu verwendende KI-Modell aus (optional, überschreibt die Standardeinstellung)"
|
"description": "Wählen Sie das zu verwendende AI-Modell (optional, überschreibt die Standardeinstellung)"
|
||||||
},
|
},
|
||||||
"temperature": {
|
"temperature": {
|
||||||
"name": "Temperatur",
|
"name": "Temperatur",
|
||||||
"description": "Steuert die Antwortkreativität (0.0-2.0)"
|
"description": "Steuert die Kreativität der Antwort (0,0-2,0)"
|
||||||
},
|
},
|
||||||
"max_tokens": {
|
"max_tokens": {
|
||||||
"name": "Max. Token",
|
"name": "Max Tokens",
|
||||||
"description": "Maximale Länge der Antwort (1-4096 Token)"
|
"description": "Maximale Länge der Antwort (1-4096 Token)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"clear_history": {
|
"clear_history": {
|
||||||
"name": "Verlauf löschen",
|
"name": "Verlauf löschen",
|
||||||
"description": "Alle gespeicherten Fragen und Antworten aus dem Konversationsverlauf löschen",
|
"description": "Löschen Sie alle gespeicherten Fragen und Antworten aus dem Gesprächsverlauf",
|
||||||
"fields": {
|
"fields": {
|
||||||
"instance": {
|
"instance": {
|
||||||
"name": "Instanz",
|
"name": "Instanz",
|
||||||
"description": "Name der HA Text AI-Instanz, deren Verlauf gelöscht werden soll"
|
"description": "Name der HA Text AI-Instanz, für die der Verlauf gelöscht werden soll"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"get_history": {
|
"get_history": {
|
||||||
"name": "Verlauf abrufen",
|
"name": "Verlauf abrufen",
|
||||||
"description": "Konversationsverlauf mit optionalem Filtern und Sortieren abrufen",
|
"description": "Rufen Sie den Gesprächsverlauf mit optionaler Filterung und Sortierung ab",
|
||||||
"fields": {
|
"fields": {
|
||||||
"instance": {
|
"instance": {
|
||||||
"name": "Instanz",
|
"name": "Instanz",
|
||||||
@@ -118,19 +148,19 @@
|
|||||||
},
|
},
|
||||||
"limit": {
|
"limit": {
|
||||||
"name": "Limit",
|
"name": "Limit",
|
||||||
"description": "Anzahl der zurückzugebenden Konversationen (1-100)"
|
"description": "Anzahl der zurückzugebenden Gespräche (1-100)"
|
||||||
},
|
},
|
||||||
"filter_model": {
|
"filter_model": {
|
||||||
"name": "Modell filtern",
|
"name": "Modell filtern",
|
||||||
"description": "Konversationen nach einem bestimmten KI-Modell filtern"
|
"description": "Gespräche nach spezifischem AI-Modell filtern"
|
||||||
},
|
},
|
||||||
"start_date": {
|
"start_date": {
|
||||||
"name": "Startdatum",
|
"name": "Startdatum",
|
||||||
"description": "Konversationen ab diesem Datum/Uhrzeit filtern"
|
"description": "Gespräche ab diesem Datum/Zeit filtern"
|
||||||
},
|
},
|
||||||
"include_metadata": {
|
"include_metadata": {
|
||||||
"name": "Metadaten einschließen",
|
"name": "Metadaten einbeziehen",
|
||||||
"description": "Zusätzliche Informationen wie verwendete Token, Antwortzeit usw. einschließen"
|
"description": "Zusätzliche Informationen wie verwendete Tokens, Antwortzeit usw. einbeziehen"
|
||||||
},
|
},
|
||||||
"sort_order": {
|
"sort_order": {
|
||||||
"name": "Sortierreihenfolge",
|
"name": "Sortierreihenfolge",
|
||||||
@@ -139,16 +169,16 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"set_system_prompt": {
|
"set_system_prompt": {
|
||||||
"name": "Systemprompt festlegen",
|
"name": "Systemaufforderung festlegen",
|
||||||
"description": "Legen Sie Standardanweisungen für das Systemverhalten für alle zukünftigen Konversationen fest",
|
"description": "Standardverhaltensanweisungen für alle zukünftigen Gespräche festlegen",
|
||||||
"fields": {
|
"fields": {
|
||||||
"instance": {
|
"instance": {
|
||||||
"name": "Instanz",
|
"name": "Instanz",
|
||||||
"description": "Name der HA Text AI-Instanz, für die der Systemprompt festgelegt werden soll"
|
"description": "Name der HA Text AI-Instanz, für die die Systemaufforderung festgelegt werden soll"
|
||||||
},
|
},
|
||||||
"prompt": {
|
"prompt": {
|
||||||
"name": "Systemprompt",
|
"name": "Systemaufforderung",
|
||||||
"description": "Anweisungen, die definieren, wie sich die KI verhalten und antworten soll"
|
"description": "Anweisungen, die definieren, wie die AI sich verhalten und antworten soll"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -162,11 +192,11 @@
|
|||||||
"processing": "Verarbeitung",
|
"processing": "Verarbeitung",
|
||||||
"error": "Fehler",
|
"error": "Fehler",
|
||||||
"disconnected": "Getrennt",
|
"disconnected": "Getrennt",
|
||||||
"rate_limited": "Ratenlimit",
|
"rate_limited": "Rate limitiert",
|
||||||
"maintenance": "Wartung",
|
"maintenance": "Wartung",
|
||||||
"initializing": "Initialisierung",
|
"initializing": "Initialisierung",
|
||||||
"retrying": "Wiederholen",
|
"retrying": "Wiederholen",
|
||||||
"queued": "Warteschlange"
|
"queued": "In der Warteschlange"
|
||||||
},
|
},
|
||||||
"state_attributes": {
|
"state_attributes": {
|
||||||
"question": {
|
"question": {
|
||||||
@@ -182,16 +212,16 @@
|
|||||||
"name": "Temperatur"
|
"name": "Temperatur"
|
||||||
},
|
},
|
||||||
"max_tokens": {
|
"max_tokens": {
|
||||||
"name": "Max. Token"
|
"name": "Max Tokens"
|
||||||
},
|
},
|
||||||
"system_prompt": {
|
"system_prompt": {
|
||||||
"name": "Systemprompt"
|
"name": "Systemaufforderung"
|
||||||
},
|
},
|
||||||
"response_time": {
|
"response_time": {
|
||||||
"name": "Letzte Antwortzeit"
|
"name": "Letzte Antwortzeit"
|
||||||
},
|
},
|
||||||
"total_responses": {
|
"total_responses": {
|
||||||
"name": "Gesamtzahl der Antworten"
|
"name": "Gesamtantworten"
|
||||||
},
|
},
|
||||||
"error_count": {
|
"error_count": {
|
||||||
"name": "Fehleranzahl"
|
"name": "Fehleranzahl"
|
||||||
@@ -203,19 +233,19 @@
|
|||||||
"name": "API-Status"
|
"name": "API-Status"
|
||||||
},
|
},
|
||||||
"tokens_used": {
|
"tokens_used": {
|
||||||
"name": "Verwendete Token insgesamt"
|
"name": "Gesamte verwendete Tokens"
|
||||||
},
|
},
|
||||||
"average_response_time": {
|
"average_response_time": {
|
||||||
"name": "Durchschnittliche Antwortzeit"
|
"name": "Durchschnittliche Antwortzeit"
|
||||||
},
|
},
|
||||||
"last_request_time": {
|
"last_request_time": {
|
||||||
"name": "Zeitpunkt der letzten Anfrage"
|
"name": "Letzte Anfragezeit"
|
||||||
},
|
},
|
||||||
"is_processing": {
|
"is_processing": {
|
||||||
"name": "Verarbeitungsstatus"
|
"name": "Verarbeitungsstatus"
|
||||||
},
|
},
|
||||||
"is_rate_limited": {
|
"is_rate_limited": {
|
||||||
"name": "Ratenlimit-Status"
|
"name": "Rate-limitiert Status"
|
||||||
},
|
},
|
||||||
"is_maintenance": {
|
"is_maintenance": {
|
||||||
"name": "Wartungsstatus"
|
"name": "Wartungsstatus"
|
||||||
@@ -224,25 +254,25 @@
|
|||||||
"name": "API-Version"
|
"name": "API-Version"
|
||||||
},
|
},
|
||||||
"endpoint_status": {
|
"endpoint_status": {
|
||||||
"name": "Endpunkt-Status"
|
"name": "Endpunktstatus"
|
||||||
},
|
},
|
||||||
"performance_metrics": {
|
"performance_metrics": {
|
||||||
"name": "Leistungsmetriken"
|
"name": "Leistungskennzahlen"
|
||||||
},
|
},
|
||||||
"history_size": {
|
"history_size": {
|
||||||
"name": "Verlaufsgröße"
|
"name": "Größe des Verlaufs"
|
||||||
},
|
},
|
||||||
"uptime": {
|
"uptime": {
|
||||||
"name": "Betriebszeit"
|
"name": "Betriebszeit"
|
||||||
},
|
},
|
||||||
"total_tokens": {
|
"total_tokens": {
|
||||||
"name": "Gesamtzahl der Token"
|
"name": "Gesamte Tokens"
|
||||||
},
|
},
|
||||||
"prompt_tokens": {
|
"prompt_tokens": {
|
||||||
"name": "Prompt-Token"
|
"name": "Eingabe Tokens"
|
||||||
},
|
},
|
||||||
"completion_tokens": {
|
"completion_tokens": {
|
||||||
"name": "Completion-Token"
|
"name": "Vervollständigungs Tokens"
|
||||||
},
|
},
|
||||||
"successful_requests": {
|
"successful_requests": {
|
||||||
"name": "Erfolgreiche Anfragen"
|
"name": "Erfolgreiche Anfragen"
|
||||||
|
|||||||
@@ -6,7 +6,23 @@
|
|||||||
"description": "Choose which AI service provider to use for this instance.",
|
"description": "Choose which AI service provider to use for this instance.",
|
||||||
"data": {
|
"data": {
|
||||||
"api_provider": "API Provider",
|
"api_provider": "API Provider",
|
||||||
"context_messages": "Number of context messages to retain (1-20)"
|
"context_messages": "Number of context messages to retain (1-20)",
|
||||||
|
"max_history_size": "Maximum conversation history size (1-100)"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"provider": {
|
||||||
|
"title": "Provider Settings",
|
||||||
|
"description": "Provide connection details for your chosen AI provider.",
|
||||||
|
"data": {
|
||||||
|
"name": "Instance name (e.g., 'GPT Assistant', 'Claude Helper')",
|
||||||
|
"api_key": "API key for authentication",
|
||||||
|
"model": "AI model to use",
|
||||||
|
"api_endpoint": "Custom API endpoint URL (optional)",
|
||||||
|
"temperature": "Response creativity (0-2, lower = more focused)",
|
||||||
|
"max_tokens": "Maximum response length (1-4096 tokens)",
|
||||||
|
"request_interval": "Minimum time between requests (0.1-60 seconds)",
|
||||||
|
"context_messages": "Number of context messages to retain (1-20)",
|
||||||
|
"max_history_size": "Maximum conversation history size (1-100)"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"user": {
|
"user": {
|
||||||
@@ -27,6 +43,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"error": {
|
"error": {
|
||||||
|
"history_storage_error": "Failed to initialize history storage. Check permissions.",
|
||||||
|
"history_rotation_error": "Error during history file rotation.",
|
||||||
|
"history_file_access_error": "Cannot access history storage directory.",
|
||||||
"name_exists": "An instance with this name already exists",
|
"name_exists": "An instance with this name already exists",
|
||||||
"invalid_name": "Invalid instance name",
|
"invalid_name": "Invalid instance name",
|
||||||
"invalid_auth": "Authentication failed - check your API key",
|
"invalid_auth": "Authentication failed - check your API key",
|
||||||
@@ -45,6 +64,9 @@
|
|||||||
"empty": "Name cannot be empty",
|
"empty": "Name cannot be empty",
|
||||||
"invalid_characters": "Name can only contain letters, numbers, spaces, underscores and hyphens",
|
"invalid_characters": "Name can only contain letters, numbers, spaces, underscores and hyphens",
|
||||||
"name_too_long": "Name must be 50 characters or less"
|
"name_too_long": "Name must be 50 characters or less"
|
||||||
|
},
|
||||||
|
"abort": {
|
||||||
|
"already_configured": "Instance already configured"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"options": {
|
"options": {
|
||||||
@@ -63,6 +85,14 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"selector": {
|
||||||
|
"api_provider": {
|
||||||
|
"options": {
|
||||||
|
"openai": "OpenAI (compatible)",
|
||||||
|
"anthropic": "Anthropic (compatible)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"services": {
|
"services": {
|
||||||
"ask_question": {
|
"ask_question": {
|
||||||
"name": "Ask Question (HA Text AI)",
|
"name": "Ask Question (HA Text AI)",
|
||||||
|
|||||||
@@ -0,0 +1,296 @@
|
|||||||
|
{
|
||||||
|
"config": {
|
||||||
|
"step": {
|
||||||
|
"provider": {
|
||||||
|
"title": "Seleccionar proveedor de IA",
|
||||||
|
"description": "Elige qué proveedor de servicio de IA utilizar para esta instancia.",
|
||||||
|
"data": {
|
||||||
|
"api_provider": "Proveedor de API",
|
||||||
|
"context_messages": "Número de mensajes de contexto a retener (1-20)",
|
||||||
|
"max_history_size": "Tamaño máximo del historial de conversación (1-100)"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"provider": {
|
||||||
|
"title": "Configuración del proveedor",
|
||||||
|
"description": "Proporciona los detalles de conexión para tu proveedor de IA elegido.",
|
||||||
|
"data": {
|
||||||
|
"name": "Nombre de la instancia (por ejemplo, 'Asistente GPT', 'Ayudante Claude')",
|
||||||
|
"api_key": "Clave API para autenticación",
|
||||||
|
"model": "Modelo de IA a utilizar",
|
||||||
|
"api_endpoint": "URL del endpoint de API personalizado (opcional)",
|
||||||
|
"temperature": "Creatividad de la respuesta (0-2, menor = más enfocado)",
|
||||||
|
"max_tokens": "Longitud máxima de la respuesta (1-4096 tokens)",
|
||||||
|
"request_interval": "Tiempo mínimo entre solicitudes (0.1-60 segundos)",
|
||||||
|
"context_messages": "Número de mensajes de contexto a retener (1-20)",
|
||||||
|
"max_history_size": "Tamaño máximo del historial de conversación (1-100)"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"user": {
|
||||||
|
"title": "Configurar instancia de IA de texto de HA",
|
||||||
|
"description": "Configura una nueva instancia de asistente de IA con tu proveedor seleccionado.",
|
||||||
|
"data": {
|
||||||
|
"name": "Nombre de la instancia (por ejemplo, 'Asistente GPT', 'Ayudante Claude')",
|
||||||
|
"api_key": "Clave API para autenticación",
|
||||||
|
"model": "Modelo de IA a utilizar",
|
||||||
|
"temperature": "Creatividad de la respuesta (0-2, menor = más enfocado)",
|
||||||
|
"max_tokens": "Longitud máxima de la respuesta (1-4096 tokens)",
|
||||||
|
"api_endpoint": "URL del endpoint de API personalizado (opcional)",
|
||||||
|
"api_provider": "Proveedor de API",
|
||||||
|
"request_interval": "Tiempo mínimo entre solicitudes (0.1-60 segundos)",
|
||||||
|
"context_messages": "Número de mensajes de contexto a retener (1-20)",
|
||||||
|
"max_history_size": "Tamaño máximo del historial de conversación (1-100)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"history_storage_error": "Error al inicializar el almacenamiento del historial. Verifica los permisos.",
|
||||||
|
"history_rotation_error": "Error durante la rotación del archivo de historial.",
|
||||||
|
"history_file_access_error": "No se puede acceder al directorio de almacenamiento del historial.",
|
||||||
|
"name_exists": "Ya existe una instancia con este nombre",
|
||||||
|
"invalid_name": "Nombre de instancia no válido",
|
||||||
|
"invalid_auth": "La autenticación falló - verifica tu clave API",
|
||||||
|
"invalid_api_key": "Clave API no válida - verifica tus credenciales",
|
||||||
|
"cannot_connect": "Error al conectar con el servicio de API",
|
||||||
|
"invalid_model": "El modelo seleccionado no está disponible",
|
||||||
|
"rate_limit": "Límite de tasa excedido",
|
||||||
|
"context_length": "Longitud del contexto excedida",
|
||||||
|
"rate_limit_exceeded": "Límite de tasa de API excedido",
|
||||||
|
"maintenance": "El servicio está en mantenimiento",
|
||||||
|
"invalid_response": "Respuesta de API no válida recibida",
|
||||||
|
"api_error": "Ocurrió un error en el servicio de API",
|
||||||
|
"timeout": "Se agotó el tiempo de la solicitud",
|
||||||
|
"invalid_instance": "Instancia no válida especificada",
|
||||||
|
"unknown": "Ocurrió un error inesperado",
|
||||||
|
"empty": "El nombre no puede estar vacío",
|
||||||
|
"invalid_characters": "El nombre solo puede contener letras, números, espacios, guiones bajos y guiones",
|
||||||
|
"name_too_long": "El nombre debe tener 50 caracteres o menos"
|
||||||
|
},
|
||||||
|
"abort": {
|
||||||
|
"already_configured": "Instancia ya configurada"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"step": {
|
||||||
|
"init": {
|
||||||
|
"title": "Actualizar configuración de la instancia",
|
||||||
|
"description": "Modifica la configuración para esta instancia de asistente de IA.",
|
||||||
|
"data": {
|
||||||
|
"model": "Modelo de IA",
|
||||||
|
"temperature": "Creatividad de la respuesta (0-2)",
|
||||||
|
"max_tokens": "Longitud máxima de la respuesta (1-4096)",
|
||||||
|
"request_interval": "Intervalo mínimo de solicitud (0.1-60 segundos)",
|
||||||
|
"context_messages": "Número de mensajes anteriores a incluir en el contexto (1-20)",
|
||||||
|
"max_history_size": "Tamaño máximo del historial de conversación (1-100)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"selector": {
|
||||||
|
"api_provider": {
|
||||||
|
"options": {
|
||||||
|
"openai": "OpenAI (compatible)",
|
||||||
|
"anthropic": "Anthropic (compatible)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"services": {
|
||||||
|
"ask_question": {
|
||||||
|
"name": "Hacer Pregunta (HA Text AI)",
|
||||||
|
"description": "Envía una pregunta al modelo de IA y recibe una respuesta detallada. La respuesta se almacenará en el historial de conversación y se podrá recuperar más tarde.",
|
||||||
|
"fields": {
|
||||||
|
"instance": {
|
||||||
|
"name": "Instancia",
|
||||||
|
"description": "Nombre de la instancia de IA de Texto de HA a utilizar"
|
||||||
|
},
|
||||||
|
"question": {
|
||||||
|
"name": "Pregunta",
|
||||||
|
"description": "Tu pregunta o solicitud para el asistente de IA"
|
||||||
|
},
|
||||||
|
"context_messages": {
|
||||||
|
"name": "Mensajes de Contexto",
|
||||||
|
"description": "Número de mensajes anteriores a incluir en el contexto (1-20)"
|
||||||
|
},
|
||||||
|
"system_prompt": {
|
||||||
|
"name": "Indicaciones del Sistema",
|
||||||
|
"description": "Indicaciones opcionales para establecer contexto para esta pregunta específica"
|
||||||
|
},
|
||||||
|
"model": {
|
||||||
|
"name": "Modelo",
|
||||||
|
"description": "Selecciona el modelo de IA a utilizar (opcional, anula la configuración predeterminada)"
|
||||||
|
},
|
||||||
|
"temperature": {
|
||||||
|
"name": "Temperatura",
|
||||||
|
"description": "Controla la creatividad de la respuesta (0.0-2.0)"
|
||||||
|
},
|
||||||
|
"max_tokens": {
|
||||||
|
"name": "Máx. Tokens",
|
||||||
|
"description": "Longitud máxima de la respuesta (1-4096 tokens)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"clear_history": {
|
||||||
|
"name": "Borrar Historial",
|
||||||
|
"description": "Elimina todas las preguntas y respuestas almacenadas del historial de conversación",
|
||||||
|
"fields": {
|
||||||
|
"instance": {
|
||||||
|
"name": "Instancia",
|
||||||
|
"description": "Nombre de la instancia de IA de Texto de HA para borrar el historial"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"get_history": {
|
||||||
|
"name": "Obtener Historial",
|
||||||
|
"description": "Recupera el historial de conversación con filtrado y ordenación opcionales",
|
||||||
|
"fields": {
|
||||||
|
"instance": {
|
||||||
|
"name": "Instancia",
|
||||||
|
"description": "Nombre de la instancia de IA de Texto de HA para obtener historial"
|
||||||
|
},
|
||||||
|
"limit": {
|
||||||
|
"name": "Límite",
|
||||||
|
"description": "Número de conversaciones a devolver (1-100)"
|
||||||
|
},
|
||||||
|
"filter_model": {
|
||||||
|
"name": "Filtrar Modelo",
|
||||||
|
"description": "Filtrar conversaciones por modelo de IA específico"
|
||||||
|
},
|
||||||
|
"start_date": {
|
||||||
|
"name": "Fecha de Inicio",
|
||||||
|
"description": "Filtrar conversaciones a partir de esta fecha/hora"
|
||||||
|
},
|
||||||
|
"include_metadata": {
|
||||||
|
"name": "Incluir Metadatos",
|
||||||
|
"description": "Incluir información adicional como tokens utilizados, tiempo de respuesta, etc."
|
||||||
|
},
|
||||||
|
"sort_order": {
|
||||||
|
"name": "Orden de Clasificación",
|
||||||
|
"description": "Orden de clasificación para los resultados (más recientes o más antiguos primero)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"set_system_prompt": {
|
||||||
|
"name": "Establecer Indicaciones del Sistema",
|
||||||
|
"description": "Establecer instrucciones de comportamiento del sistema predeterminadas para todas las futuras conversaciones",
|
||||||
|
"fields": {
|
||||||
|
"instance": {
|
||||||
|
"name": "Instancia",
|
||||||
|
"description": "Nombre de la instancia de IA de Texto de HA para establecer indicaciones del sistema"
|
||||||
|
},
|
||||||
|
"prompt": {
|
||||||
|
"name": "Indicaciones del Sistema",
|
||||||
|
"description": "Instrucciones que definen cómo debe comportarse y responder la IA"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"entity": {
|
||||||
|
"sensor": {
|
||||||
|
"ha_text_ai": {
|
||||||
|
"name": "{name}",
|
||||||
|
"state": {
|
||||||
|
"ready": "Listo",
|
||||||
|
"processing": "Procesando",
|
||||||
|
"error": "Error",
|
||||||
|
"disconnected": "Desconectado",
|
||||||
|
"rate_limited": "Limitado por tasa",
|
||||||
|
"maintenance": "Mantenimiento",
|
||||||
|
"initializing": "Inicializando",
|
||||||
|
"retrying": "Reintentando",
|
||||||
|
"queued": "En cola"
|
||||||
|
},
|
||||||
|
"state_attributes": {
|
||||||
|
"question": {
|
||||||
|
"name": "Última Pregunta"
|
||||||
|
},
|
||||||
|
"response": {
|
||||||
|
"name": "Última Respuesta"
|
||||||
|
},
|
||||||
|
"model": {
|
||||||
|
"name": "Modelo Actual"
|
||||||
|
},
|
||||||
|
"temperature": {
|
||||||
|
"name": "Temperatura"
|
||||||
|
},
|
||||||
|
"max_tokens": {
|
||||||
|
"name": "Máx. Tokens"
|
||||||
|
},
|
||||||
|
"system_prompt": {
|
||||||
|
"name": "Indicaciones del Sistema"
|
||||||
|
},
|
||||||
|
"response_time": {
|
||||||
|
"name": "Último Tiempo de Respuesta"
|
||||||
|
},
|
||||||
|
"total_responses": {
|
||||||
|
"name": "Total de Respuestas"
|
||||||
|
},
|
||||||
|
"error_count": {
|
||||||
|
"name": "Conteo de Errores"
|
||||||
|
},
|
||||||
|
"last_error": {
|
||||||
|
"name": "Último Error"
|
||||||
|
},
|
||||||
|
"api_status": {
|
||||||
|
"name": "Estado de API"
|
||||||
|
},
|
||||||
|
"tokens_used": {
|
||||||
|
"name": "Total de Tokens Usados"
|
||||||
|
},
|
||||||
|
"average_response_time": {
|
||||||
|
"name": "Tiempo de Respuesta Promedio"
|
||||||
|
},
|
||||||
|
"last_request_time": {
|
||||||
|
"name": "Último Tiempo de Solicitud"
|
||||||
|
},
|
||||||
|
"is_processing": {
|
||||||
|
"name": "Estado de Procesamiento"
|
||||||
|
},
|
||||||
|
"is_rate_limited": {
|
||||||
|
"name": "Estado Limitado por Tasa"
|
||||||
|
},
|
||||||
|
"is_maintenance": {
|
||||||
|
"name": "Estado de Mantenimiento"
|
||||||
|
},
|
||||||
|
"api_version": {
|
||||||
|
"name": "Versión de API"
|
||||||
|
},
|
||||||
|
"endpoint_status": {
|
||||||
|
"name": "Estado del Endpoint"
|
||||||
|
},
|
||||||
|
"performance_metrics": {
|
||||||
|
"name": "Métricas de Rendimiento"
|
||||||
|
},
|
||||||
|
"history_size": {
|
||||||
|
"name": "Tamaño del Historial"
|
||||||
|
},
|
||||||
|
"uptime": {
|
||||||
|
"name": "Tiempo de Actividad"
|
||||||
|
},
|
||||||
|
"total_tokens": {
|
||||||
|
"name": "Total de Tokens"
|
||||||
|
},
|
||||||
|
"prompt_tokens": {
|
||||||
|
"name": "Tokens de Solicitud"
|
||||||
|
},
|
||||||
|
"completion_tokens": {
|
||||||
|
"name": "Tokens de Finalización"
|
||||||
|
},
|
||||||
|
"successful_requests": {
|
||||||
|
"name": "Solicitudes Exitosas"
|
||||||
|
},
|
||||||
|
"failed_requests": {
|
||||||
|
"name": "Solicitudes Fallidas"
|
||||||
|
},
|
||||||
|
"average_latency": {
|
||||||
|
"name": "Latencia Promedio"
|
||||||
|
},
|
||||||
|
"max_latency": {
|
||||||
|
"name": "Latencia Máxima"
|
||||||
|
},
|
||||||
|
"min_latency": {
|
||||||
|
"name": "Latencia Mínima"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,296 @@
|
|||||||
|
{
|
||||||
|
"config": {
|
||||||
|
"step": {
|
||||||
|
"provider": {
|
||||||
|
"title": "एआई प्रदाता चुनें",
|
||||||
|
"description": "इस उदाहरण के लिए किस एआई सेवा प्रदाता का उपयोग करना है, चुनें।",
|
||||||
|
"data": {
|
||||||
|
"api_provider": "एपीआई प्रदाता",
|
||||||
|
"context_messages": "रखने के लिए संदर्भ संदेशों की संख्या (1-20)",
|
||||||
|
"max_history_size": "अधिकतम बातचीत इतिहास आकार (1-100)"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"provider": {
|
||||||
|
"title": "प्रदाता सेटिंग्स",
|
||||||
|
"description": "आपके द्वारा चुने गए एआई प्रदाता के लिए कनेक्शन विवरण प्रदान करें।",
|
||||||
|
"data": {
|
||||||
|
"name": "उदाहरण का नाम (जैसे, 'जीपीटी सहायक', 'क्लॉड सहायक')",
|
||||||
|
"api_key": "प्रमाणीकरण के लिए एपीआई कुंजी",
|
||||||
|
"model": "उपयोग करने के लिए एआई मॉडल",
|
||||||
|
"api_endpoint": "कस्टम एपीआई एंडपॉइंट यूआरएल (वैकल्पिक)",
|
||||||
|
"temperature": "प्रतिक्रिया की रचनात्मकता (0-2, कम = अधिक केंद्रित)",
|
||||||
|
"max_tokens": "प्रतिक्रिया की अधिकतम लंबाई (1-4096 टोकन)",
|
||||||
|
"request_interval": "अनुरोधों के बीच न्यूनतम समय (0.1-60 सेकंड)",
|
||||||
|
"context_messages": "रखने के लिए संदर्भ संदेशों की संख्या (1-20)",
|
||||||
|
"max_history_size": "अधिकतम बातचीत इतिहास आकार (1-100)"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"user": {
|
||||||
|
"title": "एचए टेक्स्ट एआई उदाहरण कॉन्फ़िगर करें",
|
||||||
|
"description": "अपने चुने हुए प्रदाता के साथ एक नया एआई सहायक उदाहरण सेट करें।",
|
||||||
|
"data": {
|
||||||
|
"name": "उदाहरण का नाम (जैसे, 'जीपीटी सहायक', 'क्लॉड सहायक')",
|
||||||
|
"api_key": "प्रमाणीकरण के लिए एपीआई कुंजी",
|
||||||
|
"model": "उपयोग करने के लिए एआई मॉडल",
|
||||||
|
"temperature": "प्रतिक्रिया की रचनात्मकता (0-2, कम = अधिक केंद्रित)",
|
||||||
|
"max_tokens": "प्रतिक्रिया की अधिकतम लंबाई (1-4096 टोकन)",
|
||||||
|
"api_endpoint": "कस्टम एपीआई एंडपॉइंट यूआरएल (वैकल्पिक)",
|
||||||
|
"api_provider": "एपीआई प्रदाता",
|
||||||
|
"request_interval": "अनुरोधों के बीच न्यूनतम समय (0.1-60 सेकंड)",
|
||||||
|
"context_messages": "रखने के लिए संदर्भ संदेशों की संख्या (1-20)",
|
||||||
|
"max_history_size": "अधिकतम बातचीत इतिहास आकार (1-100)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"history_storage_error": "इतिहास भंडारण प्रारंभ करने में विफल। अनुमतियों की जांच करें।",
|
||||||
|
"history_rotation_error": "इतिहास फ़ाइल घुमाने के दौरान त्रुटि।",
|
||||||
|
"history_file_access_error": "इतिहास भंडारण निर्देशिका तक पहुंच नहीं है।",
|
||||||
|
"name_exists": "इस नाम के साथ एक उदाहरण पहले से मौजूद है",
|
||||||
|
"invalid_name": "अमान्य उदाहरण नाम",
|
||||||
|
"invalid_auth": "प्रमाणीकरण विफल - अपनी एपीआई कुंजी की जांच करें",
|
||||||
|
"invalid_api_key": "अमान्य एपीआई कुंजी - कृपया अपनी क्रेडेंशियल्स की पुष्टि करें",
|
||||||
|
"cannot_connect": "एपीआई सेवा से कनेक्ट करने में विफल",
|
||||||
|
"invalid_model": "चुना हुआ मॉडल उपलब्ध नहीं है",
|
||||||
|
"rate_limit": "रेट सीमा पार",
|
||||||
|
"context_length": "संदर्भ लंबाई पार",
|
||||||
|
"rate_limit_exceeded": "एपीआई रेट सीमा पार",
|
||||||
|
"maintenance": "सेवा रखरखाव में है",
|
||||||
|
"invalid_response": "अमान्य एपीआई प्रतिक्रिया प्राप्त हुई",
|
||||||
|
"api_error": "एपीआई सेवा में त्रुटि हुई",
|
||||||
|
"timeout": "अनुरोध समय सीमा समाप्त",
|
||||||
|
"invalid_instance": "अमान्य उदाहरण निर्दिष्ट किया गया",
|
||||||
|
"unknown": "अप्रत्याशित त्रुटि हुई",
|
||||||
|
"empty": "नाम खाली नहीं हो सकता",
|
||||||
|
"invalid_characters": "नाम में केवल अक्षर, अंक, रिक्त स्थान, अंडरस्कोर और हाइफन हो सकते हैं",
|
||||||
|
"name_too_long": "नाम 50 अक्षरों या उससे कम होना चाहिए"
|
||||||
|
},
|
||||||
|
"abort": {
|
||||||
|
"already_configured": "उदाहरण पहले से कॉन्फ़िगर किया गया है"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"step": {
|
||||||
|
"init": {
|
||||||
|
"title": "उदाहरण सेटिंग्स अपडेट करें",
|
||||||
|
"description": "इस एआई सहायक उदाहरण के लिए सेटिंग्स संशोधित करें।",
|
||||||
|
"data": {
|
||||||
|
"model": "एआई मॉडल",
|
||||||
|
"temperature": "प्रतिक्रिया की रचनात्मकता (0-2)",
|
||||||
|
"max_tokens": "प्रतिक्रिया की अधिकतम लंबाई (1-4096)",
|
||||||
|
"request_interval": "न्यूनतम अनुरोध अंतराल (0.1-60 सेकंड)",
|
||||||
|
"context_messages": "संदर्भ में शामिल करने के लिए पिछले संदेशों की संख्या (1-20)",
|
||||||
|
"max_history_size": "अधिकतम बातचीत इतिहास आकार (1-100)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"selector": {
|
||||||
|
"api_provider": {
|
||||||
|
"options": {
|
||||||
|
"openai": "OpenAI (अनुकूलित)",
|
||||||
|
"anthropic": "Anthropic (अनुकूलित)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"services": {
|
||||||
|
"ask_question": {
|
||||||
|
"name": "प्रश्न पूछें (HA Text AI)",
|
||||||
|
"description": "एआई मॉडल को एक प्रश्न भेजें और विस्तृत प्रतिक्रिया प्राप्त करें। प्रतिक्रिया बातचीत के इतिहास में संग्रहीत की जाएगी और बाद में पुनर्प्राप्त की जा सकती है।",
|
||||||
|
"fields": {
|
||||||
|
"instance": {
|
||||||
|
"name": "उदाहरण",
|
||||||
|
"description": "उपयोग करने के लिए एचए टेक्स्ट एआई उदाहरण का नाम"
|
||||||
|
},
|
||||||
|
"question": {
|
||||||
|
"name": "प्रश्न",
|
||||||
|
"description": "आपका प्रश्न या एआई सहायक के लिए प्रॉम्प्ट"
|
||||||
|
},
|
||||||
|
"context_messages": {
|
||||||
|
"name": "संदर्भ संदेश",
|
||||||
|
"description": "संदर्भ में शामिल करने के लिए पिछले संदेशों की संख्या (1-20)"
|
||||||
|
},
|
||||||
|
"system_prompt": {
|
||||||
|
"name": "सिस्टम प्रॉम्प्ट",
|
||||||
|
"description": "इस विशेष प्रश्न के लिए संदर्भ सेट करने के लिए वैकल्पिक सिस्टम प्रॉम्प्ट"
|
||||||
|
},
|
||||||
|
"model": {
|
||||||
|
"name": "मॉडल",
|
||||||
|
"description": "उपयोग करने के लिए एआई मॉडल का चयन करें (वैकल्पिक, डिफ़ॉल्ट सेटिंग को ओवरराइड करता है)"
|
||||||
|
},
|
||||||
|
"temperature": {
|
||||||
|
"name": "तापमान",
|
||||||
|
"description": "प्रतिक्रिया की रचनात्मकता को नियंत्रित करता है (0.0-2.0)"
|
||||||
|
},
|
||||||
|
"max_tokens": {
|
||||||
|
"name": "अधिकतम टोकन",
|
||||||
|
"description": "प्रतिक्रिया की अधिकतम लंबाई (1-4096 टोकन)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"clear_history": {
|
||||||
|
"name": "इतिहास साफ करें",
|
||||||
|
"description": "बातचीत के इतिहास से सभी संग्रहीत प्रश्नों और प्रतिक्रियाओं को हटाएं",
|
||||||
|
"fields": {
|
||||||
|
"instance": {
|
||||||
|
"name": "उदाहरण",
|
||||||
|
"description": "इतिहास साफ़ करने के लिए एचए टेक्स्ट एआई उदाहरण का नाम"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"get_history": {
|
||||||
|
"name": "इतिहास प्राप्त करें",
|
||||||
|
"description": "वैकल्पिक फ़िल्टरिंग और छंटाई के साथ बातचीत का इतिहास प्राप्त करें",
|
||||||
|
"fields": {
|
||||||
|
"instance": {
|
||||||
|
"name": "उदाहरण",
|
||||||
|
"description": "इतिहास प्राप्त करने के लिए एचए टेक्स्ट एआई उदाहरण का नाम"
|
||||||
|
},
|
||||||
|
"limit": {
|
||||||
|
"name": "सीमा",
|
||||||
|
"description": "वापस करने के लिए बातचीत की संख्या (1-100)"
|
||||||
|
},
|
||||||
|
"filter_model": {
|
||||||
|
"name": "फिल्टर मॉडल",
|
||||||
|
"description": "विशिष्ट एआई मॉडल द्वारा बातचीत को फ़िल्टर करें"
|
||||||
|
},
|
||||||
|
"start_date": {
|
||||||
|
"name": "शुरुआत की तारीख",
|
||||||
|
"description": "इस दिन/समय से शुरू होने वाली बातचीत को फ़िल्टर करें"
|
||||||
|
},
|
||||||
|
"include_metadata": {
|
||||||
|
"name": "मेटाडेटा शामिल करें",
|
||||||
|
"description": "उपयोग किए गए टोकन, प्रतिक्रिया समय आदि जैसी अतिरिक्त जानकारी शामिल करें।"
|
||||||
|
},
|
||||||
|
"sort_order": {
|
||||||
|
"name": "छंटाई क्रम",
|
||||||
|
"description": "परिणामों के लिए छंटाई क्रम (नवीनतम या सबसे पुराना पहले)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"set_system_prompt": {
|
||||||
|
"name": "सिस्टम प्रॉम्प्ट सेट करें",
|
||||||
|
"description": "सभी भविष्य की बातचीत के लिए डिफ़ॉल्ट सिस्टम व्यवहार निर्देश सेट करें",
|
||||||
|
"fields": {
|
||||||
|
"instance": {
|
||||||
|
"name": "उदाहरण",
|
||||||
|
"description": "सिस्टम प्रॉम्प्ट सेट करने के लिए एचए टेक्स्ट एआई उदाहरण का नाम"
|
||||||
|
},
|
||||||
|
"prompt": {
|
||||||
|
"name": "सिस्टम प्रॉम्प्ट",
|
||||||
|
"description": "निर्देश जो यह परिभाषित करते हैं कि एआई को कैसे व्यवहार करना चाहिए और प्रतिक्रिया देनी चाहिए"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"entity": {
|
||||||
|
"sensor": {
|
||||||
|
"ha_text_ai": {
|
||||||
|
"name": "{name}",
|
||||||
|
"state": {
|
||||||
|
"ready": "तैयार",
|
||||||
|
"processing": "प्रसंस्करण",
|
||||||
|
"error": "त्रुटि",
|
||||||
|
"disconnected": "असंयुक्त",
|
||||||
|
"rate_limited": "रेट सीमित",
|
||||||
|
"maintenance": "रखरखाव",
|
||||||
|
"initializing": "प्रारंभिककरण",
|
||||||
|
"retrying": "पुनः प्रयास कर रहा है",
|
||||||
|
"queued": "क्यू में"
|
||||||
|
},
|
||||||
|
"state_attributes": {
|
||||||
|
"question": {
|
||||||
|
"name": "अंतिम प्रश्न"
|
||||||
|
},
|
||||||
|
"response": {
|
||||||
|
"name": "अंतिम प्रतिक्रिया"
|
||||||
|
},
|
||||||
|
"model": {
|
||||||
|
"name": "वर्तमान मॉडल"
|
||||||
|
},
|
||||||
|
"temperature": {
|
||||||
|
"name": "तापमान"
|
||||||
|
},
|
||||||
|
"max_tokens": {
|
||||||
|
"name": "अधिकतम टोकन"
|
||||||
|
},
|
||||||
|
"system_prompt": {
|
||||||
|
"name": "सिस्टम प्रॉम्प्ट"
|
||||||
|
},
|
||||||
|
"response_time": {
|
||||||
|
"name": "अंतिम प्रतिक्रिया का समय"
|
||||||
|
},
|
||||||
|
"total_responses": {
|
||||||
|
"name": "कुल प्रतिक्रियाएं"
|
||||||
|
},
|
||||||
|
"error_count": {
|
||||||
|
"name": "त्रुटियों की संख्या"
|
||||||
|
},
|
||||||
|
"last_error": {
|
||||||
|
"name": "अंतिम त्रुटि"
|
||||||
|
},
|
||||||
|
"api_status": {
|
||||||
|
"name": "एपीआई स्थिति"
|
||||||
|
},
|
||||||
|
"tokens_used": {
|
||||||
|
"name": "कुल उपयोग किए गए टोकन"
|
||||||
|
},
|
||||||
|
"average_response_time": {
|
||||||
|
"name": "औसत प्रतिक्रिया समय"
|
||||||
|
},
|
||||||
|
"last_request_time": {
|
||||||
|
"name": "अंतिम अनुरोध का समय"
|
||||||
|
},
|
||||||
|
"is_processing": {
|
||||||
|
"name": "प्रसंस्करण स्थिति"
|
||||||
|
},
|
||||||
|
"is_rate_limited": {
|
||||||
|
"name": "रेट सीमित स्थिति"
|
||||||
|
},
|
||||||
|
"is_maintenance": {
|
||||||
|
"name": "रखरखाव स्थिति"
|
||||||
|
},
|
||||||
|
"api_version": {
|
||||||
|
"name": "एपीआई संस्करण"
|
||||||
|
},
|
||||||
|
"endpoint_status": {
|
||||||
|
"name": "एंडपॉइंट स्थिति"
|
||||||
|
},
|
||||||
|
"performance_metrics": {
|
||||||
|
"name": "प्रदर्शन मैट्रिक्स"
|
||||||
|
},
|
||||||
|
"history_size": {
|
||||||
|
"name": "इतिहास का आकार"
|
||||||
|
},
|
||||||
|
"uptime": {
|
||||||
|
"name": "अपटाइम"
|
||||||
|
},
|
||||||
|
"total_tokens": {
|
||||||
|
"name": "कुल टोकन"
|
||||||
|
},
|
||||||
|
"prompt_tokens": {
|
||||||
|
"name": "प्रॉम्प्ट टोकन"
|
||||||
|
},
|
||||||
|
"completion_tokens": {
|
||||||
|
"name": "पूर्णता टोकन"
|
||||||
|
},
|
||||||
|
"successful_requests": {
|
||||||
|
"name": "सफल अनुरोध"
|
||||||
|
},
|
||||||
|
"failed_requests": {
|
||||||
|
"name": "विफल अनुरोध"
|
||||||
|
},
|
||||||
|
"average_latency": {
|
||||||
|
"name": "औसत विलंबता"
|
||||||
|
},
|
||||||
|
"max_latency": {
|
||||||
|
"name": "अधिकतम विलंबता"
|
||||||
|
},
|
||||||
|
"min_latency": {
|
||||||
|
"name": "न्यूनतम विलंबता"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,296 @@
|
|||||||
|
{
|
||||||
|
"config": {
|
||||||
|
"step": {
|
||||||
|
"provider": {
|
||||||
|
"title": "Seleziona fornitore AI",
|
||||||
|
"description": "Scegli quale fornitore di servizi AI utilizzare per questa istanza.",
|
||||||
|
"data": {
|
||||||
|
"api_provider": "Fornitore API",
|
||||||
|
"context_messages": "Numero di messaggi di contesto da mantenere (1-20)",
|
||||||
|
"max_history_size": "Dimensione massima della cronologia delle conversazioni (1-100)"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"provider": {
|
||||||
|
"title": "Impostazioni fornitore",
|
||||||
|
"description": "Fornisci i dettagli di connessione per il tuo fornitore di AI scelto.",
|
||||||
|
"data": {
|
||||||
|
"name": "Nome dell'istanza (es. 'Assistente GPT', 'Aiuto Claude')",
|
||||||
|
"api_key": "Chiave API per l'autenticazione",
|
||||||
|
"model": "Modello AI da utilizzare",
|
||||||
|
"api_endpoint": "URL dell'endpoint API personalizzato (opzionale)",
|
||||||
|
"temperature": "Creatività della risposta (0-2, più basso = più focalizzato)",
|
||||||
|
"max_tokens": "Lunghezza massima della risposta (1-4096 token)",
|
||||||
|
"request_interval": "Tempo minimo tra le richieste (0.1-60 secondi)",
|
||||||
|
"context_messages": "Numero di messaggi di contesto da mantenere (1-20)",
|
||||||
|
"max_history_size": "Dimensione massima della cronologia delle conversazioni (1-100)"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"user": {
|
||||||
|
"title": "Configura istanza AI di testo HA",
|
||||||
|
"description": "Imposta una nuova istanza di assistente AI con il fornitore selezionato.",
|
||||||
|
"data": {
|
||||||
|
"name": "Nome dell'istanza (es. 'Assistente GPT', 'Aiuto Claude')",
|
||||||
|
"api_key": "Chiave API per l'autenticazione",
|
||||||
|
"model": "Modello AI da utilizzare",
|
||||||
|
"temperature": "Creatività della risposta (0-2, più basso = più focalizzato)",
|
||||||
|
"max_tokens": "Lunghezza massima della risposta (1-4096 token)",
|
||||||
|
"api_endpoint": "URL dell'endpoint API personalizzato (opzionale)",
|
||||||
|
"api_provider": "Fornitore API",
|
||||||
|
"request_interval": "Tempo minimo tra le richieste (0.1-60 secondi)",
|
||||||
|
"context_messages": "Numero di messaggi di contesto da mantenere (1-20)",
|
||||||
|
"max_history_size": "Dimensione massima della cronologia delle conversazioni (1-100)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"history_storage_error": "Impossibile inizializzare la memorizzazione della cronologia. Controlla i permessi.",
|
||||||
|
"history_rotation_error": "Errore durante la rotazione del file di cronologia.",
|
||||||
|
"history_file_access_error": "Impossibile accedere alla directory di memorizzazione della cronologia.",
|
||||||
|
"name_exists": "Esiste già un'istanza con questo nome",
|
||||||
|
"invalid_name": "Nome dell'istanza non valido",
|
||||||
|
"invalid_auth": "Autenticazione fallita - controlla la tua chiave API",
|
||||||
|
"invalid_api_key": "Chiave API non valida - verifica le tue credenziali",
|
||||||
|
"cannot_connect": "Impossibile connettersi al servizio API",
|
||||||
|
"invalid_model": "Il modello selezionato non è disponibile",
|
||||||
|
"rate_limit": "Limite di frequenza superato",
|
||||||
|
"context_length": "Lunghezza del contesto superata",
|
||||||
|
"rate_limit_exceeded": "Limite di frequenza API superato",
|
||||||
|
"maintenance": "Il servizio è in manutenzione",
|
||||||
|
"invalid_response": "Risposta API non valida ricevuta",
|
||||||
|
"api_error": "Si è verificato un errore nel servizio API",
|
||||||
|
"timeout": "Richiesta scaduta",
|
||||||
|
"invalid_instance": "Istanze specificata non valida",
|
||||||
|
"unknown": "Si è verificato un errore imprevisto",
|
||||||
|
"empty": "Il nome non può essere vuoto",
|
||||||
|
"invalid_characters": "Il nome può contenere solo lettere, numeri, spazi, trattini bassi e trattini",
|
||||||
|
"name_too_long": "Il nome deve essere lungo 50 caratteri o meno"
|
||||||
|
},
|
||||||
|
"abort": {
|
||||||
|
"already_configured": "Istanze già configurata"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"step": {
|
||||||
|
"init": {
|
||||||
|
"title": "Aggiorna impostazioni dell'istanza",
|
||||||
|
"description": "Modifica le impostazioni per questa istanza di assistente AI.",
|
||||||
|
"data": {
|
||||||
|
"model": "Modello AI",
|
||||||
|
"temperature": "Creatività della risposta (0-2)",
|
||||||
|
"max_tokens": "Lunghezza massima della risposta (1-4096)",
|
||||||
|
"request_interval": "Intervallo minimo di richiesta (0.1-60 secondi)",
|
||||||
|
"context_messages": "Numero di messaggi precedenti da includere nel contesto (1-20)",
|
||||||
|
"max_history_size": "Dimensione massima della cronologia delle conversazioni (1-100)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"selector": {
|
||||||
|
"api_provider": {
|
||||||
|
"options": {
|
||||||
|
"openai": "OpenAI (compatibile)",
|
||||||
|
"anthropic": "Anthropic (compatibile)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"services": {
|
||||||
|
"ask_question": {
|
||||||
|
"name": "Fai una domanda (HA Text AI)",
|
||||||
|
"description": "Invia una domanda al modello AI e ricevi una risposta dettagliata. La risposta sarà memorizzata nella cronologia delle conversazioni e potrà essere recuperata in seguito.",
|
||||||
|
"fields": {
|
||||||
|
"instance": {
|
||||||
|
"name": "Istanze",
|
||||||
|
"description": "Nome dell'istanza HA Text AI da utilizzare"
|
||||||
|
},
|
||||||
|
"question": {
|
||||||
|
"name": "Domanda",
|
||||||
|
"description": "La tua domanda o richiesta per l'assistente AI"
|
||||||
|
},
|
||||||
|
"context_messages": {
|
||||||
|
"name": "Messaggi di contesto",
|
||||||
|
"description": "Numero di messaggi precedenti da includere nel contesto (1-20)"
|
||||||
|
},
|
||||||
|
"system_prompt": {
|
||||||
|
"name": "Prompt di sistema",
|
||||||
|
"description": "Prompt di sistema opzionale per impostare il contesto per questa specifica domanda"
|
||||||
|
},
|
||||||
|
"model": {
|
||||||
|
"name": "Modello",
|
||||||
|
"description": "Seleziona il modello AI da utilizzare (opzionale, sovrascrive l'impostazione predefinita)"
|
||||||
|
},
|
||||||
|
"temperature": {
|
||||||
|
"name": "Temperatura",
|
||||||
|
"description": "Controlla la creatività della risposta (0.0-2.0)"
|
||||||
|
},
|
||||||
|
"max_tokens": {
|
||||||
|
"name": "Token massimi",
|
||||||
|
"description": "Lunghezza massima della risposta (1-4096 token)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"clear_history": {
|
||||||
|
"name": "Cancella cronologia",
|
||||||
|
"description": "Elimina tutte le domande e risposte memorizzate dalla cronologia delle conversazioni",
|
||||||
|
"fields": {
|
||||||
|
"instance": {
|
||||||
|
"name": "Istanze",
|
||||||
|
"description": "Nome dell'istanza HA Text AI per cui cancellare la cronologia"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"get_history": {
|
||||||
|
"name": "Ottieni cronologia",
|
||||||
|
"description": "Recupera la cronologia delle conversazioni con opzioni di filtro e ordinamento",
|
||||||
|
"fields": {
|
||||||
|
"instance": {
|
||||||
|
"name": "Istanze",
|
||||||
|
"description": "Nome dell'istanza HA Text AI da cui recuperare la cronologia"
|
||||||
|
},
|
||||||
|
"limit": {
|
||||||
|
"name": "Limite",
|
||||||
|
"description": "Numero di conversazioni da restituire (1-100)"
|
||||||
|
},
|
||||||
|
"filter_model": {
|
||||||
|
"name": "Filtra modello",
|
||||||
|
"description": "Filtra le conversazioni per modello AI specifico"
|
||||||
|
},
|
||||||
|
"start_date": {
|
||||||
|
"name": "Data di inizio",
|
||||||
|
"description": "Filtra le conversazioni a partire da questa data/ora"
|
||||||
|
},
|
||||||
|
"include_metadata": {
|
||||||
|
"name": "Includi metadati",
|
||||||
|
"description": "Includi informazioni aggiuntive come token utilizzati, tempo di risposta, ecc."
|
||||||
|
},
|
||||||
|
"sort_order": {
|
||||||
|
"name": "Ordine di ordinamento",
|
||||||
|
"description": "Ordine di ordinamento per i risultati (più recenti o più vecchi per primi)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"set_system_prompt": {
|
||||||
|
"name": "Imposta prompt di sistema",
|
||||||
|
"description": "Imposta le istruzioni di comportamento predefinite per tutte le future conversazioni",
|
||||||
|
"fields": {
|
||||||
|
"instance": {
|
||||||
|
"name": "Istanze",
|
||||||
|
"description": "Nome dell'istanza HA Text AI per cui impostare il prompt di sistema"
|
||||||
|
},
|
||||||
|
"prompt": {
|
||||||
|
"name": "Prompt di sistema",
|
||||||
|
"description": "Istruzioni che definiscono come l'AI dovrebbe comportarsi e rispondere"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"entity": {
|
||||||
|
"sensor": {
|
||||||
|
"ha_text_ai": {
|
||||||
|
"name": "{name}",
|
||||||
|
"state": {
|
||||||
|
"ready": "Pronto",
|
||||||
|
"processing": "Elaborazione",
|
||||||
|
"error": "Errore",
|
||||||
|
"disconnected": "Disconnesso",
|
||||||
|
"rate_limited": "Limite di frequenza",
|
||||||
|
"maintenance": "Manutenzione",
|
||||||
|
"initializing": "Inizializzazione",
|
||||||
|
"retrying": "Riprova",
|
||||||
|
"queued": "In coda"
|
||||||
|
},
|
||||||
|
"state_attributes": {
|
||||||
|
"question": {
|
||||||
|
"name": "Ultima domanda"
|
||||||
|
},
|
||||||
|
"response": {
|
||||||
|
"name": "Ultima risposta"
|
||||||
|
},
|
||||||
|
"model": {
|
||||||
|
"name": "Modello attuale"
|
||||||
|
},
|
||||||
|
"temperature": {
|
||||||
|
"name": "Temperatura"
|
||||||
|
},
|
||||||
|
"max_tokens": {
|
||||||
|
"name": "Token massimi"
|
||||||
|
},
|
||||||
|
"system_prompt": {
|
||||||
|
"name": "Prompt di sistema"
|
||||||
|
},
|
||||||
|
"response_time": {
|
||||||
|
"name": "Ultimo tempo di risposta"
|
||||||
|
},
|
||||||
|
"total_responses": {
|
||||||
|
"name": "Risposte totali"
|
||||||
|
},
|
||||||
|
"error_count": {
|
||||||
|
"name": "Conteggio errori"
|
||||||
|
},
|
||||||
|
"last_error": {
|
||||||
|
"name": "Ultimo errore"
|
||||||
|
},
|
||||||
|
"api_status": {
|
||||||
|
"name": "Stato API"
|
||||||
|
},
|
||||||
|
"tokens_used": {
|
||||||
|
"name": "Token totali utilizzati"
|
||||||
|
},
|
||||||
|
"average_response_time": {
|
||||||
|
"name": "Tempo medio di risposta"
|
||||||
|
},
|
||||||
|
"last_request_time": {
|
||||||
|
"name": "Ultimo tempo di richiesta"
|
||||||
|
},
|
||||||
|
"is_processing": {
|
||||||
|
"name": "Stato di elaborazione"
|
||||||
|
},
|
||||||
|
"is_rate_limited": {
|
||||||
|
"name": "Stato limite di frequenza"
|
||||||
|
},
|
||||||
|
"is_maintenance": {
|
||||||
|
"name": "Stato di manutenzione"
|
||||||
|
},
|
||||||
|
"api_version": {
|
||||||
|
"name": "Versione API"
|
||||||
|
},
|
||||||
|
"endpoint_status": {
|
||||||
|
"name": "Stato dell'endpoint"
|
||||||
|
},
|
||||||
|
"performance_metrics": {
|
||||||
|
"name": "Metriche di prestazione"
|
||||||
|
},
|
||||||
|
"history_size": {
|
||||||
|
"name": "Dimensione della cronologia"
|
||||||
|
},
|
||||||
|
"uptime": {
|
||||||
|
"name": "Tempo di attività"
|
||||||
|
},
|
||||||
|
"total_tokens": {
|
||||||
|
"name": "Token totali"
|
||||||
|
},
|
||||||
|
"prompt_tokens": {
|
||||||
|
"name": "Token di prompt"
|
||||||
|
},
|
||||||
|
"completion_tokens": {
|
||||||
|
"name": "Token di completamento"
|
||||||
|
},
|
||||||
|
"successful_requests": {
|
||||||
|
"name": "Richieste riuscite"
|
||||||
|
},
|
||||||
|
"failed_requests": {
|
||||||
|
"name": "Richieste fallite"
|
||||||
|
},
|
||||||
|
"average_latency": {
|
||||||
|
"name": "Latenza media"
|
||||||
|
},
|
||||||
|
"max_latency": {
|
||||||
|
"name": "Latenza massima"
|
||||||
|
},
|
||||||
|
"min_latency": {
|
||||||
|
"name": "Latenza minima"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,98 +2,128 @@
|
|||||||
"config": {
|
"config": {
|
||||||
"step": {
|
"step": {
|
||||||
"provider": {
|
"provider": {
|
||||||
"title": "Выбор поставщика ИИ",
|
"title": "Выбор провайдера ИИ",
|
||||||
"description": "Выберите поставщика услуг ИИ для этой инстанции.",
|
"description": "Выберите сервис искусственного интеллекта для этого экземпляра.",
|
||||||
"data": {
|
"data": {
|
||||||
"api_provider": "Поставщик API",
|
"api_provider": "Провайдер API",
|
||||||
"context_messages": "Количество контекстных сообщений для сохранения (1-20)"
|
"context_messages": "Количество сохраняемых контекстных сообщений (1-20)",
|
||||||
|
"max_history_size": "Максимальный размер истории разговора (1-100)"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"provider": {
|
||||||
|
"title": "Настройки провайдера",
|
||||||
|
"description": "Укажите параметры подключения для выбранного провайдера ИИ.",
|
||||||
|
"data": {
|
||||||
|
"name": "Название экземпляра (например, 'GPT Помощник', 'Клод Ассистент')",
|
||||||
|
"api_key": "API-ключ для аутентификации",
|
||||||
|
"model": "Модель ИИ для использования",
|
||||||
|
"api_endpoint": "Пользовательский URL-адрес конечной точки API (необязательно)",
|
||||||
|
"temperature": "Креативность ответа (0-2, меньше = более сфокусированно)",
|
||||||
|
"max_tokens": "Максимальная длина ответа (1-4096 токенов)",
|
||||||
|
"request_interval": "Минимальный интервал между запросами (0.1-60 секунд)",
|
||||||
|
"context_messages": "Количество сохраняемых контекстных сообщений (1-20)",
|
||||||
|
"max_history_size": "Максимальный размер истории разговора (1-100)"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"user": {
|
"user": {
|
||||||
"title": "Настройка инстанции HA Text AI",
|
"title": "Настройка экземпляра текстового ИИ для Home Assistant",
|
||||||
"description": "Настройте новую инстанцию помощника ИИ с выбранным вами поставщиком.",
|
"description": "Настройте новый экземпляр ИИ-помощника с выбранным провайдером.",
|
||||||
"data": {
|
"data": {
|
||||||
"name": "Имя инстанции (например, 'GPT Assistant', 'Claude Helper')",
|
"name": "Название экземпляра (например, 'GPT Помощник', 'Клод Ассистент')",
|
||||||
"api_key": "API-ключ для аутентификации",
|
"api_key": "API-ключ для аутентификации",
|
||||||
"model": "Используемая модель ИИ",
|
"model": "Модель ИИ для использования",
|
||||||
"temperature": "Креативность ответа (0-2, чем ниже, тем больше фокусировки)",
|
"temperature": "Креативность ответа (0-2, меньше = более сфокусированно)",
|
||||||
"max_tokens": "Максимальная длина ответа (1-4096 токенов)",
|
"max_tokens": "Максимальная длина ответа (1-4096 токенов)",
|
||||||
"api_endpoint": "Пользовательский URL-адрес конечной точки API (необязательно)",
|
"api_endpoint": "Пользовательский URL-адрес конечной точки API (необязательно)",
|
||||||
"api_provider": "Поставщик API",
|
"api_provider": "Провайдер API",
|
||||||
"request_interval": "Минимальное время между запросами (0,1-60 секунд)",
|
"request_interval": "Минимальный интервал между запросами (0.1-60 секунд)",
|
||||||
"context_messages": "Количество контекстных сообщений для сохранения (1-20)",
|
"context_messages": "Количество сохраняемых контекстных сообщений (1-20)",
|
||||||
"max_history_size": "Максимальный размер истории разговора (1-100)"
|
"max_history_size": "Максимальный размер истории разговора (1-100)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"error": {
|
"error": {
|
||||||
"name_exists": "Инстанция с таким именем уже существует",
|
"history_storage_error": "Не удалось инициализировать хранилище истории. Проверьте разрешения.",
|
||||||
"invalid_name": "Некорректное имя инстанции",
|
"history_rotation_error": "Ошибка при ротации файла истории.",
|
||||||
"invalid_auth": "Аутентификация не удалась - проверьте ваш API-ключ",
|
"history_file_access_error": "Невозможно получить доступ к директории хранения истории.",
|
||||||
"invalid_api_key": "Неверный API-ключ - проверьте ваши учетные данные",
|
"name_exists": "Экземпляр с таким именем уже существует",
|
||||||
"cannot_connect": "Не удалось подключиться к службе API",
|
"invalid_name": "Недопустимое имя экземпляра",
|
||||||
|
"invalid_auth": "Ошибка аутентификации - проверьте API-ключ",
|
||||||
|
"invalid_api_key": "Недопустимый API-ключ - пожалуйста, проверьте учетные данные",
|
||||||
|
"cannot_connect": "Не удалось подключиться к сервису API",
|
||||||
"invalid_model": "Выбранная модель недоступна",
|
"invalid_model": "Выбранная модель недоступна",
|
||||||
"rate_limit": "Превышен лимит запросов",
|
"rate_limit": "Превышен лимит запросов",
|
||||||
"context_length": "Превышена длина контекста",
|
"context_length": "Превышена длина контекста",
|
||||||
"rate_limit_exceeded": "Превышен лимит запросов API",
|
"rate_limit_exceeded": "Превышен лимит запросов API",
|
||||||
"maintenance": "Сервис находится на техническом обслуживании",
|
"maintenance": "Сервис находится на техническом обслуживании",
|
||||||
"invalid_response": "Получен неверный ответ API",
|
"invalid_response": "Получен некорректный ответ API",
|
||||||
"api_error": "Произошла ошибка службы API",
|
"api_error": "Произошла ошибка сервиса API",
|
||||||
"timeout": "Запрос превысил время ожидания",
|
"timeout": "Время ожидания запроса истекло",
|
||||||
"invalid_instance": "Указана неверная инстанция",
|
"invalid_instance": "Указан некорректный экземпляр",
|
||||||
"unknown": "Произошла непредвиденная ошибка",
|
"unknown": "Произошла непредвиденная ошибка",
|
||||||
"empty": "Имя не может быть пустым",
|
"empty": "Имя не может быть пустым",
|
||||||
"invalid_characters": "Имя может содержать только буквы, цифры, пробелы, подчеркивания и дефисы",
|
"invalid_characters": "Имя может содержать только буквы, цифры, пробелы, подчеркивания и дефисы",
|
||||||
"name_too_long": "Имя должно быть не более 50 символов"
|
"name_too_long": "Имя должно быть не длиннее 50 символов"
|
||||||
|
},
|
||||||
|
"abort": {
|
||||||
|
"already_configured": "Экземпляр уже настроен"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"options": {
|
"options": {
|
||||||
"step": {
|
"step": {
|
||||||
"init": {
|
"init": {
|
||||||
"title": "Обновление настроек инстанции",
|
"title": "Обновление настроек экземпляра",
|
||||||
"description": "Измените настройки для этой инстанции помощника ИИ.",
|
"description": "Измените настройки для этого экземпляра ИИ-помощника.",
|
||||||
"data": {
|
"data": {
|
||||||
"model": "Модель ИИ",
|
"model": "Модель ИИ",
|
||||||
"temperature": "Креативность ответа (0-2)",
|
"temperature": "Креативность ответа (0-2)",
|
||||||
"max_tokens": "Максимальная длина ответа (1-4096)",
|
"max_tokens": "Максимальная длина ответа (1-4096)",
|
||||||
"request_interval": "Минимальный интервал между запросами (0,1-60 секунд)",
|
"request_interval": "Минимальный интервал между запросами (0.1-60 секунд)",
|
||||||
"context_messages": "Количество предыдущих сообщений для включения в контекст (1-20)",
|
"context_messages": "Количество предыдущих сообщений для включения в контекст (1-20)",
|
||||||
"max_history_size": "Максимальный размер истории разговора (1-100)"
|
"max_history_size": "Максимальный размер истории разговора (1-100)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"selector": {
|
||||||
|
"api_provider": {
|
||||||
|
"options": {
|
||||||
|
"openai": "OpenAI (совместимый)",
|
||||||
|
"anthropic": "Anthropic (совместимый)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"services": {
|
"services": {
|
||||||
"ask_question": {
|
"ask_question": {
|
||||||
"name": "Задать вопрос (HA Text AI)",
|
"name": "Задать вопрос (HA Text AI)",
|
||||||
"description": "Отправьте вопрос модели ИИ и получите подробный ответ. Ответ будет сохранен в истории разговора и может быть извлечен позже.",
|
"description": "Отправить вопрос модели ИИ и получить подробный ответ. Ответ будет сохранен в истории разговора и может быть получен позже.",
|
||||||
"fields": {
|
"fields": {
|
||||||
"instance": {
|
"instance": {
|
||||||
"name": "Инстанция",
|
"name": "Экземпляр",
|
||||||
"description": "Имя используемой инстанции HA Text AI"
|
"description": "Название экземпляра текстового ИИ для использования"
|
||||||
},
|
},
|
||||||
"question": {
|
"question": {
|
||||||
"name": "Вопрос",
|
"name": "Вопрос",
|
||||||
"description": "Ваш вопрос или запрос к помощнику ИИ"
|
"description": "Ваш вопрос или запрос к ИИ-помощнику"
|
||||||
},
|
},
|
||||||
"context_messages": {
|
"context_messages": {
|
||||||
"name": "Контекстные сообщения",
|
"name": "Контекстные сообщения",
|
||||||
"description": "Количество предыдущих сообщений для включения в контекст (1-20)"
|
"description": "Количество предыдущих сообщений для включения в контекст (1-20)"
|
||||||
},
|
},
|
||||||
"system_prompt": {
|
"system_prompt": {
|
||||||
"name": "Системный запрос",
|
"name": "Системный промпт",
|
||||||
"description": "Необязательный системный запрос для установки контекста для этого конкретного вопроса"
|
"description": "Необязательный системный промпт для установки контекста для этого конкретного вопроса"
|
||||||
},
|
},
|
||||||
"model": {
|
"model": {
|
||||||
"name": "Модель",
|
"name": "Модель",
|
||||||
"description": "Выберите модель ИИ для использования (необязательно, переопределяет настройку по умолчанию)"
|
"description": "Выберите модель ИИ для использования (необязательно, переопределяет настройки по умолчанию)"
|
||||||
},
|
},
|
||||||
"temperature": {
|
"temperature": {
|
||||||
"name": "Температура",
|
"name": "Температура",
|
||||||
"description": "Управляет креативностью ответа (0.0-2.0)"
|
"description": "Управление креативностью ответа (0.0-2.0)"
|
||||||
},
|
},
|
||||||
"max_tokens": {
|
"max_tokens": {
|
||||||
"name": "Макс. токенов",
|
"name": "Максимум токенов",
|
||||||
"description": "Максимальная длина ответа (1-4096 токенов)"
|
"description": "Максимальная длина ответа (1-4096 токенов)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -103,18 +133,18 @@
|
|||||||
"description": "Удалить все сохраненные вопросы и ответы из истории разговора",
|
"description": "Удалить все сохраненные вопросы и ответы из истории разговора",
|
||||||
"fields": {
|
"fields": {
|
||||||
"instance": {
|
"instance": {
|
||||||
"name": "Инстанция",
|
"name": "Экземпляр",
|
||||||
"description": "Имя инстанции HA Text AI, для которой нужно очистить историю"
|
"description": "Название экземпляра текстового ИИ для очистки истории"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"get_history": {
|
"get_history": {
|
||||||
"name": "Получить историю",
|
"name": "Получить историю",
|
||||||
"description": "Извлечь историю разговора с возможностью фильтрации и сортировки",
|
"description": "Получить историю разговора с дополнительной фильтрацией и сортировкой",
|
||||||
"fields": {
|
"fields": {
|
||||||
"instance": {
|
"instance": {
|
||||||
"name": "Инстанция",
|
"name": "Экземпляр",
|
||||||
"description": "Имя инстанции HA Text AI, из которой нужно получить историю"
|
"description": "Название экземпляра текстового ИИ для получения истории"
|
||||||
},
|
},
|
||||||
"limit": {
|
"limit": {
|
||||||
"name": "Лимит",
|
"name": "Лимит",
|
||||||
@@ -122,33 +152,33 @@
|
|||||||
},
|
},
|
||||||
"filter_model": {
|
"filter_model": {
|
||||||
"name": "Фильтр модели",
|
"name": "Фильтр модели",
|
||||||
"description": "Фильтрация разговоров по определенной модели ИИ"
|
"description": "Фильтрация разговоров по конкретной модели ИИ"
|
||||||
},
|
},
|
||||||
"start_date": {
|
"start_date": {
|
||||||
"name": "Дата начала",
|
"name": "Начальная дата",
|
||||||
"description": "Фильтрация разговоров, начиная с этой даты/времени"
|
"description": "Фильтрация разговоров, начиная с указанной даты/времени"
|
||||||
},
|
},
|
||||||
"include_metadata": {
|
"include_metadata": {
|
||||||
"name": "Включить метаданные",
|
"name": "Включить метаданные",
|
||||||
"description": "Включить дополнительную информацию, такую как использованные токены, время ответа и т.д."
|
"description": "Включить дополнительную информацию, например, использованные токены, время ответа и т.д."
|
||||||
},
|
},
|
||||||
"sort_order": {
|
"sort_order": {
|
||||||
"name": "Порядок сортировки",
|
"name": "Порядок сортировки",
|
||||||
"description": "Порядок сортировки результатов (самые новые или самые старые)"
|
"description": "Порядок сортировки результатов (сначала новые или старые)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"set_system_prompt": {
|
"set_system_prompt": {
|
||||||
"name": "Установить системный запрос",
|
"name": "Установить системный промпт",
|
||||||
"description": "Установить инструкции по умолчанию для поведения системы для всех будущих разговоров",
|
"description": "Установить инструкции по умолчанию для поведения ИИ во всех будущих разговорах",
|
||||||
"fields": {
|
"fields": {
|
||||||
"instance": {
|
"instance": {
|
||||||
"name": "Инстанция",
|
"name": "Экземпляр",
|
||||||
"description": "Имя инстанции HA Text AI, для которой нужно установить системный запрос"
|
"description": "Название экземпляра текстового ИИ для установки системного промпта"
|
||||||
},
|
},
|
||||||
"prompt": {
|
"prompt": {
|
||||||
"name": "Системный запрос",
|
"name": "Системный промпт",
|
||||||
"description": "Инструкции, определяющие, как ИИ должен себя вести и отвечать"
|
"description": "Инструкции, определяющие, как ИИ должен вести себя и отвечать"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -182,10 +212,10 @@
|
|||||||
"name": "Температура"
|
"name": "Температура"
|
||||||
},
|
},
|
||||||
"max_tokens": {
|
"max_tokens": {
|
||||||
"name": "Макс. токенов"
|
"name": "Максимум токенов"
|
||||||
},
|
},
|
||||||
"system_prompt": {
|
"system_prompt": {
|
||||||
"name": "Системный запрос"
|
"name": "Системный промпт"
|
||||||
},
|
},
|
||||||
"response_time": {
|
"response_time": {
|
||||||
"name": "Время последнего ответа"
|
"name": "Время последнего ответа"
|
||||||
@@ -203,7 +233,7 @@
|
|||||||
"name": "Статус API"
|
"name": "Статус API"
|
||||||
},
|
},
|
||||||
"tokens_used": {
|
"tokens_used": {
|
||||||
"name": "Использовано токенов всего"
|
"name": "Всего использовано токенов"
|
||||||
},
|
},
|
||||||
"average_response_time": {
|
"average_response_time": {
|
||||||
"name": "Среднее время ответа"
|
"name": "Среднее время ответа"
|
||||||
@@ -215,10 +245,10 @@
|
|||||||
"name": "Статус обработки"
|
"name": "Статус обработки"
|
||||||
},
|
},
|
||||||
"is_rate_limited": {
|
"is_rate_limited": {
|
||||||
"name": "Статус ограничения запросов"
|
"name": "Статус лимита запросов"
|
||||||
},
|
},
|
||||||
"is_maintenance": {
|
"is_maintenance": {
|
||||||
"name": "Статус технического обслуживания"
|
"name": "Статус обслуживания"
|
||||||
},
|
},
|
||||||
"api_version": {
|
"api_version": {
|
||||||
"name": "Версия API"
|
"name": "Версия API"
|
||||||
@@ -227,7 +257,7 @@
|
|||||||
"name": "Статус конечной точки"
|
"name": "Статус конечной точки"
|
||||||
},
|
},
|
||||||
"performance_metrics": {
|
"performance_metrics": {
|
||||||
"name": "Метрики производительности"
|
"name": "Показатели производительности"
|
||||||
},
|
},
|
||||||
"history_size": {
|
"history_size": {
|
||||||
"name": "Размер истории"
|
"name": "Размер истории"
|
||||||
@@ -239,16 +269,16 @@
|
|||||||
"name": "Всего токенов"
|
"name": "Всего токенов"
|
||||||
},
|
},
|
||||||
"prompt_tokens": {
|
"prompt_tokens": {
|
||||||
"name": "Токены запроса"
|
"name": "Токены промпта"
|
||||||
},
|
},
|
||||||
"completion_tokens": {
|
"completion_tokens": {
|
||||||
"name": "Токены завершения"
|
"name": "Токены завершения"
|
||||||
},
|
},
|
||||||
"successful_requests": {
|
"successful_requests": {
|
||||||
"name": "Успешных запросов"
|
"name": "Успешные запросы"
|
||||||
},
|
},
|
||||||
"failed_requests": {
|
"failed_requests": {
|
||||||
"name": "Неудачных запросов"
|
"name": "Неудачные запросы"
|
||||||
},
|
},
|
||||||
"average_latency": {
|
"average_latency": {
|
||||||
"name": "Средняя задержка"
|
"name": "Средняя задержка"
|
||||||
|
|||||||
@@ -0,0 +1,296 @@
|
|||||||
|
{
|
||||||
|
"config": {
|
||||||
|
"step": {
|
||||||
|
"provider": {
|
||||||
|
"title": "Изаберите AI провајдера",
|
||||||
|
"description": "Изаберите који AI сервис провајдер да користите за ову инстанцу.",
|
||||||
|
"data": {
|
||||||
|
"api_provider": "API провајдер",
|
||||||
|
"context_messages": "Број контекстуалних порука које треба задржати (1-20)",
|
||||||
|
"max_history_size": "Максимална величина историје разговора (1-100)"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"provider": {
|
||||||
|
"title": "Подешавања провајдера",
|
||||||
|
"description": "Обезбедите детаље о вези за изабраног AI провајдера.",
|
||||||
|
"data": {
|
||||||
|
"name": "Име инстанце (нпр. 'GPT Асистент', 'Claude Помоћник')",
|
||||||
|
"api_key": "API кључ за аутентификацију",
|
||||||
|
"model": "AI модел који ће се користити",
|
||||||
|
"api_endpoint": "Прилагођени URL API крајње тачке (опционо)",
|
||||||
|
"temperature": "Креативност одговора (0-2, нижа = фокусираније)",
|
||||||
|
"max_tokens": "Максимална дужина одговора (1-4096 токена)",
|
||||||
|
"request_interval": "Минимално време између захтева (0.1-60 секунди)",
|
||||||
|
"context_messages": "Број контекстуалних порука које треба задржати (1-20)",
|
||||||
|
"max_history_size": "Максимална величина историје разговора (1-100)"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"user": {
|
||||||
|
"title": "Конфигуришите HA Text AI инстанцу",
|
||||||
|
"description": "Подесите нову AI асистент инстанцу са изабраним провајдером.",
|
||||||
|
"data": {
|
||||||
|
"name": "Име инстанце (нпр. 'GPT Асистент', 'Claude Помоћник')",
|
||||||
|
"api_key": "API кључ за аутентификацију",
|
||||||
|
"model": "AI модел који ће се користити",
|
||||||
|
"temperature": "Креативност одговора (0-2, нижа = фокусираније)",
|
||||||
|
"max_tokens": "Максимална дужина одговора (1-4096 токена)",
|
||||||
|
"api_endpoint": "Прилагођени URL API крајње тачке (опционо)",
|
||||||
|
"api_provider": "API провајдер",
|
||||||
|
"request_interval": "Минимално време између захтева (0.1-60 секунди)",
|
||||||
|
"context_messages": "Број контекстуалних порука које треба задржати (1-20)",
|
||||||
|
"max_history_size": "Максимална величина историје разговора (1-100)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"history_storage_error": "Неуспела инициализација складишта историје. Проверите дозволе.",
|
||||||
|
"history_rotation_error": "Грешка током ротације историјских датотека.",
|
||||||
|
"history_file_access_error": "Немогуће приступити директоријуму складишта историје.",
|
||||||
|
"name_exists": "Инстанца са овим именом већ постоји",
|
||||||
|
"invalid_name": "Неважеће име инстанце",
|
||||||
|
"invalid_auth": "Аутентификација није успела - проверите ваш API кључ",
|
||||||
|
"invalid_api_key": "Неважећи API кључ - молимо проверите ваше акредитиве",
|
||||||
|
"cannot_connect": "Неуспело повезивање са API сервисом",
|
||||||
|
"invalid_model": "Изабрани модел није доступан",
|
||||||
|
"rate_limit": "Пређена граница захтева",
|
||||||
|
"context_length": "Дужина контекста пређена",
|
||||||
|
"rate_limit_exceeded": "Пређена граница API захтева",
|
||||||
|
"maintenance": "Сервис је у одржавању",
|
||||||
|
"invalid_response": "Примљен неважећи API одговор",
|
||||||
|
"api_error": "Дошло је до грешке у API сервису",
|
||||||
|
"timeout": "Време захтева је истекло",
|
||||||
|
"invalid_instance": "Неважећа инстанца је назначена",
|
||||||
|
"unknown": "Дошло је до неочекиване грешке",
|
||||||
|
"empty": "Име не може бити празно",
|
||||||
|
"invalid_characters": "Име може садржавати само слова, цифре, размаке, подцрта и цртице",
|
||||||
|
"name_too_long": "Име мора бити 50 знакова или мање"
|
||||||
|
},
|
||||||
|
"abort": {
|
||||||
|
"already_configured": "Инстанца је већ конфигурисана"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"step": {
|
||||||
|
"init": {
|
||||||
|
"title": "Ажурирајте подешавања инстанце",
|
||||||
|
"description": "Измените подешавања за ову AI асистент инстанцу.",
|
||||||
|
"data": {
|
||||||
|
"model": "AI модел",
|
||||||
|
"temperature": "Креативност одговора (0-2)",
|
||||||
|
"max_tokens": "Максимална дужина одговора (1-4096)",
|
||||||
|
"request_interval": "Минимално време између захтева (0.1-60 секунди)",
|
||||||
|
"context_messages": "Број претходних порука које треба укључити у контекст (1-20)",
|
||||||
|
"max_history_size": "Максимална величина историје разговора (1-100)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"selector": {
|
||||||
|
"api_provider": {
|
||||||
|
"options": {
|
||||||
|
"openai": "OpenAI (компатибилан)",
|
||||||
|
"anthropic": "Anthropic (компатибилан)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"services": {
|
||||||
|
"ask_question": {
|
||||||
|
"name": "Поставите питање (HA Text AI)",
|
||||||
|
"description": "Пошаљите питање AI моделу и примите детаљан одговор. Одговор ће бити сачуван у историји разговора и може се касније повратити.",
|
||||||
|
"fields": {
|
||||||
|
"instance": {
|
||||||
|
"name": "Инстанца",
|
||||||
|
"description": "Име HA Text AI инстанце коју ћете користити"
|
||||||
|
},
|
||||||
|
"question": {
|
||||||
|
"name": "Питање",
|
||||||
|
"description": "Ваше питање или упит за AI асистента"
|
||||||
|
},
|
||||||
|
"context_messages": {
|
||||||
|
"name": "Контекстуалне поруке",
|
||||||
|
"description": "Број претходних порука које треба укључити у контекст (1-20)"
|
||||||
|
},
|
||||||
|
"system_prompt": {
|
||||||
|
"name": "Системски упит",
|
||||||
|
"description": "Опционални системски упит за постављање контекста за ово конкретно питање"
|
||||||
|
},
|
||||||
|
"model": {
|
||||||
|
"name": "Модел",
|
||||||
|
"description": "Изаберите AI модел који ћете користити (опционо, надмашује подразумевану поставку)"
|
||||||
|
},
|
||||||
|
"temperature": {
|
||||||
|
"name": "Температура",
|
||||||
|
"description": "Контролише креативност одговора (0.0-2.0)"
|
||||||
|
},
|
||||||
|
"max_tokens": {
|
||||||
|
"name": "Максимални токени",
|
||||||
|
"description": "Максимална дужина одговора (1-4096 токена)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"clear_history": {
|
||||||
|
"name": "Обриши историју",
|
||||||
|
"description": "Избришите све сачуване питања и одговоре из историје разговора",
|
||||||
|
"fields": {
|
||||||
|
"instance": {
|
||||||
|
"name": "Инстанца",
|
||||||
|
"description": "Име HA Text AI инстанце за коју желите да обришете историју"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"get_history": {
|
||||||
|
"name": "Добијте историју",
|
||||||
|
"description": "Повратите историју разговора уз опционално филтрирање и сортирање",
|
||||||
|
"fields": {
|
||||||
|
"instance": {
|
||||||
|
"name": "Инстанца",
|
||||||
|
"description": "Име HA Text AI инстанце из које желите да добијете историју"
|
||||||
|
},
|
||||||
|
"limit": {
|
||||||
|
"name": "Лимит",
|
||||||
|
"description": "Број разговора које треба вратити (1-100)"
|
||||||
|
},
|
||||||
|
"filter_model": {
|
||||||
|
"name": "Филтер модел",
|
||||||
|
"description": "Филтрирајте разговоре по одређеном AI моделу"
|
||||||
|
},
|
||||||
|
"start_date": {
|
||||||
|
"name": "Датум почетка",
|
||||||
|
"description": "Филтрирајте разговоре који почињу од овог датума/времена"
|
||||||
|
},
|
||||||
|
"include_metadata": {
|
||||||
|
"name": "Укључи метаподатке",
|
||||||
|
"description": "Укључите додатне информације као што су коришћени токени, време одговора итд."
|
||||||
|
},
|
||||||
|
"sort_order": {
|
||||||
|
"name": "Редослед сортирања",
|
||||||
|
"description": "Редослед сортирања за резултате (најновији или најстарији први)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"set_system_prompt": {
|
||||||
|
"name": "Поставите системски упит",
|
||||||
|
"description": "Поставите подразумеване инструкције за системско понашање за све будуће разговоре",
|
||||||
|
"fields": {
|
||||||
|
"instance": {
|
||||||
|
"name": "Инстанца",
|
||||||
|
"description": "Име HA Text AI инстанце за коју желите да поставите системски упит"
|
||||||
|
},
|
||||||
|
"prompt": {
|
||||||
|
"name": "Системски упит",
|
||||||
|
"description": "Инструкције које дефинишу како AI треба да се понаша и одговара"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"entity": {
|
||||||
|
"sensor": {
|
||||||
|
"ha_text_ai": {
|
||||||
|
"name": "{name}",
|
||||||
|
"state": {
|
||||||
|
"ready": "Спремно",
|
||||||
|
"processing": "Обрада",
|
||||||
|
"error": "Грешка",
|
||||||
|
"disconnected": "Прекључено",
|
||||||
|
"rate_limited": "Ограничење захтева",
|
||||||
|
"maintenance": "Одржавање",
|
||||||
|
"initializing": "Инициализује се",
|
||||||
|
"retrying": "Покушава поново",
|
||||||
|
"queued": "У реду"
|
||||||
|
},
|
||||||
|
"state_attributes": {
|
||||||
|
"question": {
|
||||||
|
"name": "Последње питање"
|
||||||
|
},
|
||||||
|
"response": {
|
||||||
|
"name": "Последњи одговор"
|
||||||
|
},
|
||||||
|
"model": {
|
||||||
|
"name": "Тренутни модел"
|
||||||
|
},
|
||||||
|
"temperature": {
|
||||||
|
"name": "Температура"
|
||||||
|
},
|
||||||
|
"max_tokens": {
|
||||||
|
"name": "Максимални токени"
|
||||||
|
},
|
||||||
|
"system_prompt": {
|
||||||
|
"name": "Системски упит"
|
||||||
|
},
|
||||||
|
"response_time": {
|
||||||
|
"name": "Време последњег одговора"
|
||||||
|
},
|
||||||
|
"total_responses": {
|
||||||
|
"name": "Укупно одговора"
|
||||||
|
},
|
||||||
|
"error_count": {
|
||||||
|
"name": "Број грешака"
|
||||||
|
},
|
||||||
|
"last_error": {
|
||||||
|
"name": "Последња грешка"
|
||||||
|
},
|
||||||
|
"api_status": {
|
||||||
|
"name": "Статус API"
|
||||||
|
},
|
||||||
|
"tokens_used": {
|
||||||
|
"name": "Укупно коришћени токени"
|
||||||
|
},
|
||||||
|
"average_response_time": {
|
||||||
|
"name": "Просечно време одговора"
|
||||||
|
},
|
||||||
|
"last_request_time": {
|
||||||
|
"name": "Време последњег захтева"
|
||||||
|
},
|
||||||
|
"is_processing": {
|
||||||
|
"name": "Статус обраде"
|
||||||
|
},
|
||||||
|
"is_rate_limited": {
|
||||||
|
"name": "Статус ограничења захтева"
|
||||||
|
},
|
||||||
|
"is_maintenance": {
|
||||||
|
"name": "Статус одржавања"
|
||||||
|
},
|
||||||
|
"api_version": {
|
||||||
|
"name": "Верзија API"
|
||||||
|
},
|
||||||
|
"endpoint_status": {
|
||||||
|
"name": "Статус крајње тачке"
|
||||||
|
},
|
||||||
|
"performance_metrics": {
|
||||||
|
"name": "Перформансне метрике"
|
||||||
|
},
|
||||||
|
"history_size": {
|
||||||
|
"name": "Величина историје"
|
||||||
|
},
|
||||||
|
"uptime": {
|
||||||
|
"name": "Уптиме"
|
||||||
|
},
|
||||||
|
"total_tokens": {
|
||||||
|
"name": "Укупно токена"
|
||||||
|
},
|
||||||
|
"prompt_tokens": {
|
||||||
|
"name": "Токени упита"
|
||||||
|
},
|
||||||
|
"completion_tokens": {
|
||||||
|
"name": "Токени завршетка"
|
||||||
|
},
|
||||||
|
"successful_requests": {
|
||||||
|
"name": "Успешни захтеви"
|
||||||
|
},
|
||||||
|
"failed_requests": {
|
||||||
|
"name": "Неуспешни захтеви"
|
||||||
|
},
|
||||||
|
"average_latency": {
|
||||||
|
"name": "Просечна латенција"
|
||||||
|
},
|
||||||
|
"max_latency": {
|
||||||
|
"name": "Максимална латенција"
|
||||||
|
},
|
||||||
|
"min_latency": {
|
||||||
|
"name": "Минимална латенција"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,296 @@
|
|||||||
|
{
|
||||||
|
"config": {
|
||||||
|
"step": {
|
||||||
|
"provider": {
|
||||||
|
"title": "选择AI提供者",
|
||||||
|
"description": "选择要用于此实例的AI服务提供者。",
|
||||||
|
"data": {
|
||||||
|
"api_provider": "API提供者",
|
||||||
|
"context_messages": "保留的上下文消息数量(1-20)",
|
||||||
|
"max_history_size": "最大对话历史大小(1-100)"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"provider": {
|
||||||
|
"title": "提供者设置",
|
||||||
|
"description": "提供所选AI提供者的连接详细信息。",
|
||||||
|
"data": {
|
||||||
|
"name": "实例名称(例如,'GPT助手','Claude助手')",
|
||||||
|
"api_key": "用于身份验证的API密钥",
|
||||||
|
"model": "要使用的AI模型",
|
||||||
|
"api_endpoint": "自定义API端点URL(可选)",
|
||||||
|
"temperature": "响应创造力(0-2,越低越专注)",
|
||||||
|
"max_tokens": "最大响应长度(1-4096个标记)",
|
||||||
|
"request_interval": "请求之间的最小时间(0.1-60秒)",
|
||||||
|
"context_messages": "保留的上下文消息数量(1-20)",
|
||||||
|
"max_history_size": "最大对话历史大小(1-100)"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"user": {
|
||||||
|
"title": "配置HA文本AI实例",
|
||||||
|
"description": "使用所选提供者设置新的AI助手实例。",
|
||||||
|
"data": {
|
||||||
|
"name": "实例名称(例如,'GPT助手','Claude助手')",
|
||||||
|
"api_key": "用于身份验证的API密钥",
|
||||||
|
"model": "要使用的AI模型",
|
||||||
|
"temperature": "响应创造力(0-2,越低越专注)",
|
||||||
|
"max_tokens": "最大响应长度(1-4096个标记)",
|
||||||
|
"api_endpoint": "自定义API端点URL(可选)",
|
||||||
|
"api_provider": "API提供者",
|
||||||
|
"request_interval": "请求之间的最小时间(0.1-60秒)",
|
||||||
|
"context_messages": "保留的上下文消息数量(1-20)",
|
||||||
|
"max_history_size": "最大对话历史大小(1-100)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"history_storage_error": "无法初始化历史存储。检查权限。",
|
||||||
|
"history_rotation_error": "历史文件轮换时出错。",
|
||||||
|
"history_file_access_error": "无法访问历史存储目录。",
|
||||||
|
"name_exists": "具有此名称的实例已存在",
|
||||||
|
"invalid_name": "无效的实例名称",
|
||||||
|
"invalid_auth": "身份验证失败 - 检查您的API密钥",
|
||||||
|
"invalid_api_key": "无效的API密钥 - 请验证您的凭据",
|
||||||
|
"cannot_connect": "无法连接到API服务",
|
||||||
|
"invalid_model": "所选模型不可用",
|
||||||
|
"rate_limit": "超出速率限制",
|
||||||
|
"context_length": "上下文长度超出限制",
|
||||||
|
"rate_limit_exceeded": "API速率限制超出",
|
||||||
|
"maintenance": "服务正在维护中",
|
||||||
|
"invalid_response": "收到无效的API响应",
|
||||||
|
"api_error": "发生API服务错误",
|
||||||
|
"timeout": "请求超时",
|
||||||
|
"invalid_instance": "指定的实例无效",
|
||||||
|
"unknown": "发生意外错误",
|
||||||
|
"empty": "名称不能为空",
|
||||||
|
"invalid_characters": "名称只能包含字母、数字、空格、下划线和连字符",
|
||||||
|
"name_too_long": "名称必须少于50个字符"
|
||||||
|
},
|
||||||
|
"abort": {
|
||||||
|
"already_configured": "实例已配置"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"step": {
|
||||||
|
"init": {
|
||||||
|
"title": "更新实例设置",
|
||||||
|
"description": "修改此AI助手实例的设置。",
|
||||||
|
"data": {
|
||||||
|
"model": "AI模型",
|
||||||
|
"temperature": "响应创造力(0-2)",
|
||||||
|
"max_tokens": "最大响应长度(1-4096)",
|
||||||
|
"request_interval": "最小请求间隔(0.1-60秒)",
|
||||||
|
"context_messages": "要包含在上下文中的先前消息数量(1-20)",
|
||||||
|
"max_history_size": "最大对话历史大小(1-100)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"selector": {
|
||||||
|
"api_provider": {
|
||||||
|
"options": {
|
||||||
|
"openai": "OpenAI(兼容)",
|
||||||
|
"anthropic": "Anthropic(兼容)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"services": {
|
||||||
|
"ask_question": {
|
||||||
|
"name": "提问 (HA Text AI)",
|
||||||
|
"description": "向AI模型发送问题并接收详细响应。响应将存储在对话历史中,可以稍后检索。",
|
||||||
|
"fields": {
|
||||||
|
"instance": {
|
||||||
|
"name": "实例",
|
||||||
|
"description": "要使用的HA文本AI实例名称"
|
||||||
|
},
|
||||||
|
"question": {
|
||||||
|
"name": "问题",
|
||||||
|
"description": "您对AI助手的问题或提示"
|
||||||
|
},
|
||||||
|
"context_messages": {
|
||||||
|
"name": "上下文消息",
|
||||||
|
"description": "要包含在上下文中的先前消息数量(1-20)"
|
||||||
|
},
|
||||||
|
"system_prompt": {
|
||||||
|
"name": "系统提示",
|
||||||
|
"description": "可选的系统提示,用于为此特定问题设置上下文"
|
||||||
|
},
|
||||||
|
"model": {
|
||||||
|
"name": "模型",
|
||||||
|
"description": "选择要使用的AI模型(可选,覆盖默认设置)"
|
||||||
|
},
|
||||||
|
"temperature": {
|
||||||
|
"name": "温度",
|
||||||
|
"description": "控制响应创造力(0.0-2.0)"
|
||||||
|
},
|
||||||
|
"max_tokens": {
|
||||||
|
"name": "最大标记数",
|
||||||
|
"description": "响应的最大长度(1-4096个标记)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"clear_history": {
|
||||||
|
"name": "清除历史",
|
||||||
|
"description": "删除对话历史中存储的所有问题和响应",
|
||||||
|
"fields": {
|
||||||
|
"instance": {
|
||||||
|
"name": "实例",
|
||||||
|
"description": "要清除历史的HA文本AI实例名称"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"get_history": {
|
||||||
|
"name": "获取历史",
|
||||||
|
"description": "检索对话历史,可选的过滤和排序",
|
||||||
|
"fields": {
|
||||||
|
"instance": {
|
||||||
|
"name": "实例",
|
||||||
|
"description": "要获取历史的HA文本AI实例名称"
|
||||||
|
},
|
||||||
|
"limit": {
|
||||||
|
"name": "限制",
|
||||||
|
"description": "要返回的对话数量(1-100)"
|
||||||
|
},
|
||||||
|
"filter_model": {
|
||||||
|
"name": "过滤模型",
|
||||||
|
"description": "按特定AI模型过滤对话"
|
||||||
|
},
|
||||||
|
"start_date": {
|
||||||
|
"name": "开始日期",
|
||||||
|
"description": "过滤从此日期/时间开始的对话"
|
||||||
|
},
|
||||||
|
"include_metadata": {
|
||||||
|
"name": "包含元数据",
|
||||||
|
"description": "包括额外信息,如使用的标记、响应时间等。"
|
||||||
|
},
|
||||||
|
"sort_order": {
|
||||||
|
"name": "排序顺序",
|
||||||
|
"description": "结果的排序顺序(最新或最旧优先)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"set_system_prompt": {
|
||||||
|
"name": "设置系统提示",
|
||||||
|
"description": "为所有未来的对话设置默认的系统行为指令",
|
||||||
|
"fields": {
|
||||||
|
"instance": {
|
||||||
|
"name": "实例",
|
||||||
|
"description": "要设置系统提示的HA文本AI实例名称"
|
||||||
|
},
|
||||||
|
"prompt": {
|
||||||
|
"name": "系统提示",
|
||||||
|
"description": "定义AI应如何行为和响应的指令"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"entity": {
|
||||||
|
"sensor": {
|
||||||
|
"ha_text_ai": {
|
||||||
|
"name": "{name}",
|
||||||
|
"state": {
|
||||||
|
"ready": "准备就绪",
|
||||||
|
"processing": "处理中",
|
||||||
|
"error": "错误",
|
||||||
|
"disconnected": "已断开连接",
|
||||||
|
"rate_limited": "速率限制",
|
||||||
|
"maintenance": "维护中",
|
||||||
|
"initializing": "初始化中",
|
||||||
|
"retrying": "重试中",
|
||||||
|
"queued": "排队中"
|
||||||
|
},
|
||||||
|
"state_attributes": {
|
||||||
|
"question": {
|
||||||
|
"name": "最后问题"
|
||||||
|
},
|
||||||
|
"response": {
|
||||||
|
"name": "最后响应"
|
||||||
|
},
|
||||||
|
"model": {
|
||||||
|
"name": "当前模型"
|
||||||
|
},
|
||||||
|
"temperature": {
|
||||||
|
"name": "温度"
|
||||||
|
},
|
||||||
|
"max_tokens": {
|
||||||
|
"name": "最大标记数"
|
||||||
|
},
|
||||||
|
"system_prompt": {
|
||||||
|
"name": "系统提示"
|
||||||
|
},
|
||||||
|
"response_time": {
|
||||||
|
"name": "最后响应时间"
|
||||||
|
},
|
||||||
|
"total_responses": {
|
||||||
|
"name": "总响应数"
|
||||||
|
},
|
||||||
|
"error_count": {
|
||||||
|
"name": "错误计数"
|
||||||
|
},
|
||||||
|
"last_error": {
|
||||||
|
"name": "最后错误"
|
||||||
|
},
|
||||||
|
"api_status": {
|
||||||
|
"name": "API状态"
|
||||||
|
},
|
||||||
|
"tokens_used": {
|
||||||
|
"name": "总使用标记数"
|
||||||
|
},
|
||||||
|
"average_response_time": {
|
||||||
|
"name": "平均响应时间"
|
||||||
|
},
|
||||||
|
"last_request_time": {
|
||||||
|
"name": "最后请求时间"
|
||||||
|
},
|
||||||
|
"is_processing": {
|
||||||
|
"name": "处理状态"
|
||||||
|
},
|
||||||
|
"is_rate_limited": {
|
||||||
|
"name": "速率限制状态"
|
||||||
|
},
|
||||||
|
"is_maintenance": {
|
||||||
|
"name": "维护状态"
|
||||||
|
},
|
||||||
|
"api_version": {
|
||||||
|
"name": "API版本"
|
||||||
|
},
|
||||||
|
"endpoint_status": {
|
||||||
|
"name": "端点状态"
|
||||||
|
},
|
||||||
|
"performance_metrics": {
|
||||||
|
"name": "性能指标"
|
||||||
|
},
|
||||||
|
"history_size": {
|
||||||
|
"name": "历史大小"
|
||||||
|
},
|
||||||
|
"uptime": {
|
||||||
|
"name": "正常运行时间"
|
||||||
|
},
|
||||||
|
"total_tokens": {
|
||||||
|
"name": "总标记数"
|
||||||
|
},
|
||||||
|
"prompt_tokens": {
|
||||||
|
"name": "提示标记数"
|
||||||
|
},
|
||||||
|
"completion_tokens": {
|
||||||
|
"name": "完成标记数"
|
||||||
|
},
|
||||||
|
"successful_requests": {
|
||||||
|
"name": "成功请求数"
|
||||||
|
},
|
||||||
|
"failed_requests": {
|
||||||
|
"name": "失败请求数"
|
||||||
|
},
|
||||||
|
"average_latency": {
|
||||||
|
"name": "平均延迟"
|
||||||
|
},
|
||||||
|
"max_latency": {
|
||||||
|
"name": "最大延迟"
|
||||||
|
},
|
||||||
|
"min_latency": {
|
||||||
|
"name": "最小延迟"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,25 +1,30 @@
|
|||||||
```
|
```
|
||||||
ha-text-ai/
|
ha_text_ai/
|
||||||
│
|
├── __init__.py
|
||||||
├── custom_components/
|
├── api_client.py
|
||||||
├── ha_text_ai/
|
├── config_flow.py
|
||||||
│ ├── __init__.py
|
├── const.py
|
||||||
│ ├── config_flow.py
|
├── coordinator.py
|
||||||
│ ├── coordinator.py
|
├── icons
|
||||||
│ ├── manifest.json
|
│ ├── dark_icon.png
|
||||||
│ ├── sensor.py
|
│ ├── dark_icon@2x.png
|
||||||
│ ├── services.yaml
|
│ ├── dark_logo.png
|
||||||
│ ├── const.py
|
│ ├── dark_logo@2x.png
|
||||||
│ └── api_client.py
|
│ ├── icon.png
|
||||||
│
|
│ ├── icon@2x.png
|
||||||
├── translations/
|
│ ├── logo.png
|
||||||
│ ├── en.json
|
│ └── logo@2x.png
|
||||||
│ ├── de.json
|
├── manifest.json
|
||||||
│ └── ru.json
|
├── sensor.py
|
||||||
│
|
├── services.yaml
|
||||||
└── icons/
|
└── translations
|
||||||
├── icon.png
|
├── de.json
|
||||||
├── icon@2x.png
|
├── en.json
|
||||||
├── logo.png
|
├── es.json
|
||||||
└── logo@2x.png
|
├── hi.json
|
||||||
|
├── it.json
|
||||||
|
├── ru.json
|
||||||
|
├── sr.json
|
||||||
|
└── zh.json
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|||||||