Typescript / Javascript 库来扩展 Cognigy.AI 4 带有自己代码的平台.
目录
安装
使用 npm :
npm i @cognigy/extension-tools
使用线条 :
yarn add @cognigy/extension-tools
文件夹结构
- 扩展名
- 读取
- 曲线/
- 节点/
- 我的花节点( T)
- 连接/
- 我的连接.ts
- 模块.ts
- 软件包.json
- 软件包锁.json
- tslint.json (英语)
- tsconfig.json (英语)
- 图标.png
- 节点/
这个结构包括建立和上传扩展至Cognigy所需的全部资源. 大赦国际。 README.md用于显示代码的内容. 因此,其他开发者或感兴趣的用户可以熟悉该功能. 暴露出流程节点的整个源代码位于 src/nodes/ 文件夹,其中使用下四个文件(package.json, package-lock.json,tslint.json,tsconfig.json)来创建Javascript模块并检查出错。 图标需要在Cognigy中显示模块的标志. 大赦国际。 在大多数情况下,图标显示了我们与之相融合的第三方软件产品的标志.
注释:
- 图标.png需要以下维度: 64x64 像素
示例
导入扩展工具
为了使用所提供的接口和功能,需要从每个文件中导入国家防范机制软件包:
模块.ts
import { createExtension } from "@cognigy/extension-tools";
连接.ts
import { IConnectionSchema } from "@cognigy/extension-tools";
流节点.ts
import { createNodeDescriptor, INodeFunctionBaseParams } from "@cognigy/extension-tools";
知识.ts
import { createKnowledgeConnector } from "@cognigy/extension-tools";
连接
A 类 连接 可以通过下列格式创建,而字段列表则定义了用户需要提供的Cognigy内部证书值列表. 大赦国际:
import { IConnectionSchema } from "@cognigy/extension-tools";
export const myConnection: IConnectionSchema = {
type: "myconnection",
label: "Basic Auth",
fields: [
{ fieldName: "username" },
{ fieldName: "password" }
]
};
如果扩展应提供多个连接, 例如 Basic Auth, OAuth2 和 API 密钥, 每个连接在自己的文件中定义 :
- 连接/
- basicAuthConnection.ts 互联网档案馆的存檔,存档日期2013-12-02
- oauthConnection.ts (英语)
- apiKey 连接.ts
流程节点
扩展 流程节点 通过描述创建 fields, (中文(简体) ), sections 财务报告和审定财务报表 function例如,虽然这个软件包提供了一种称为“使用”的方法 createNodeDescriptor() 为了遵循必要的接口:
import { createNodeDescriptor, INodeFunctionBaseParams } from "@cognigy/extension-tools";
export interface IMyParams extends INodeFunctionBaseParams {
config: {};
}
export const myFlowNode = createNodeDescriptor({
type: "myFlowNode",
defaultLabel: "My Flow Node",
fields: [],
function: async ({ cognigy, config }: IMyParams) => {}
});
现在这个最小的设置可以被信息所填充:
import { createNodeDescriptor, INodeFunctionBaseParams } from "@cognigy/extension-tools";
export interface IMyParams extends INodeFunctionBaseParams {
config: {
text: string;
};
}
export const myFlowNode = createNodeDescriptor({
type: "myFlowNode",
defaultLabel: "My Flow Node",
fields: [
{
key: "text",
label: "Text",
type: "cognigyText",
defaultValue: "{{input.text}}",
params: {
required: true
}
},
],
function: async ({ cognigy, config }: IMyParams) => {
const { api } = cognigy;
const { text } = config;
api.say(`You said ${text}`);
}
});
除了这个伪代码的例子,人们可以在 GitHub 扩展仓库。 。 。 .
如果扩展提供了多个流程节点,每个节点在自己的文件中被定义:
- 节点/
- 创建联系( C)
- 获取联系
- 搜索( t)
知识连接器
您可以创建 知识连接器 通过描述 fields, (中文(简体) ), sections 财务报告和审定财务报表 function本套件提供了 createKnowledgeConnector() 用于跟踪必要接口的方法.
您可以进一步自定义 Knowledge Connectionor 格式,如 外地科。 。 。 .
import { createKnowledgeConnector } from "@cognigy/extension-tools";
export const myKnowledgeConnector = createKnowledgeConnector({
type: "myKnowledgeConnector",
label: "My Knowledge Connector",
summary: "My own Knowledge Connector",
fields: [] as const,
function: async ({ config, api }) => {
// Knowledge Connector logic
},
});
以下示例显示一个知识连接器的最小设置 :
import * as crypto from "node:crypto";
import { createKnowledgeConnector } from "@cognigy/extension-tools";
export const myKnowledgeConnector = createKnowledgeConnector({
type: "myKnowledgeConnector",
label: "My Knowledge Connector",
summary: "My own Knowledge Extension",
fields: [
{
key: "name",
label: "Name",
type: "text",
params: {
required: true,
},
},
{
key: "color",
label: "Color",
type: "text",
params: {
required: true,
},
},
] as const, // usage of "as const" provides type safety for config keys inside `function` method
function: async ({ config, api, sources }) => {
const text = `The color of ${config.name} is ${config.color}`;
const contentHash = crypto.hash("sha256", text, "hex");
// Create or update a Knowledge Source.
// upsertKnowledgeSource identifies if source needs to be re-ingested or not based on
// externalIdentifier, chunkCount, and contentHashOrTimestamp
// - In case of update, the knowledgeSource with temporary name is returned,
// which later replaced the original source on last successful chunk ingestion.
// - In case of create, the knowledgeSource with original name is returned.
// - In case no ingestion is required, it returns null, however, description and tags are always updated
// The externalIdentifier defaults to the source name if not explicitly set.
const knowledgeSource = await api.upsertKnowledgeSource({
name: config.name,
description: "This is my own knowledge source",
tags: ["example"],
chunkCount: 1,
contentHashOrTimestamp: contentHash, // Used to identify if the content has changed
});
// Add data to your Knowledge Source
if (knowledgeSource) {
await api.createKnowledgeChunk({
knowledgeSourceId: knowledgeSource.knowledgeSourceId,
text,
data: {},
});
}
// Delete old sources that were created by the connector but are no longer needed
const createdSources = [config.name];
for (const source of sources) {
// Use source.externalIdentifier instead of source.name for comparison,
// as the source name may be changed (e.g. "My Source" -> "My Source (1)")
// to handle duplicate names across the Knowledge Store.
if (!createdSources.includes(source.externalIdentifier)) {
await api.deleteKnowledgeSource({
knowledgeSourceId: source.knowledgeSourceId,
});
}
}
},
});
模块/扩展
最后,您可以使用描述的流程节点,知识连接器和连接来创建扩展. 为此目的,本套件提供 createExtension() 函数 :
import { createExtension } from "@cognigy/extension-tools";
import { myConnection } from "./connections/myConnection";
import { myFlowNode } from "./nodes/myFlowNode";
import { myKnowledgeConnector } from "./knowledge/myKnowledgeConnector";
export default createExtension({
nodes: [
myFlowNode
],
knowledge: [
myKnowledgeConnector
],
connections: [
myConnection
]
});
使用量
外地科
与其在它们之间显示所有配置的字段,不如将其组织成使用 sections 财务报告和审定财务报表 form 属性,改进节点编辑器的用户体验.
在这个例子中,节点的形式会是这样结构的:
- 外地 1
- 第1节
- 外地 2
- 外地 3
- 第2节
- 外地 4
- 外地 5
createNodeDescriptor({
// ...
fields: [
// ... (field1, field2, field3, field4, field5)
],
sections: [
{
key: "section1",
label: "Section 1",
fields: ["field1", "field2"]
},
{
key: "section2",
label: "Section 2",
fields: ["field3", "field4"]
}
],
form: [
{
key: "field1",
type: "field"
},
{
key: "section1",
type: "section"
},
{
key: "section2",
type: "section"
}
]
});
外观自定义
可以自定义一个节点的外观来提高节点在流编辑器中的类型和内容配置的可识别性.
在这个例子中,"流节点"将有一个带有暗色文字的浅粉色颜色,"流"的第二行将预览所配置的值 field1 字段.
createNodeDescriptor({
// ... (field1)
appearance: {
color: "#FFAABB",
textColor: "#222222"
},
preview: {
key: "field1",
type: "text"
}
});
键
当扩展安装时,一个节点可以通过定义 tokens 节。 当节点将数据写入对话时, 这会有所帮助 context ,然后可以通过 CognigyScript 编辑器中的图形符号轻松访问.
以下节点让一个名为Concogy Token的用户方便地获取其结果值 Some Node Result 用于例如Say节点.
createNodeDescriptor({
// ...
function: async ({ cognigy }) => {
// ...
cognigy.context.someNodeResult = "example result";
},
tokens: [
{
type: "context",
label: "Some Node Result",
script: "context.someNodeResult"
}
]
});
有条件的字段
可以基于节点配置的其他部分有条件地显示字段和段落,以提升Flow构建器的用户体验.
场和科 condition 配置属性只有在符合其配置条件时才会在节点编辑器UI中可见.
有条件的字段
在这个例子中,领域 field2 仅显示在 field1 实值 true。 。 。 .
createNodeDescriptor({
// ...
fields: [
{
key: "field1",
type: "toggle",
// ...
defaultValue: false,
},
{
key: "field2",
// ...
condition: {
key: "field1",
value: true
}
}
]
});
在这个例子中, field2 将仅显示在 field1 实值 "example"。 。 。 .
createNodeDescriptor({
// ...
fields: [
{
key: "field1",
type: "text",
// ...
},
{
key: "field2",
// ...
condition: {
key: "field1",
value: "example"
}
}
]
});
在这个例子中, field2 将仅显示在 field1 无论是 "example1" 或者说 "example2"。 。 。 .
createNodeDescriptor({
// ...
fields: [
{
key: "field1",
type: "text",
// ...
},
{
key: "field2",
// ...
condition: {
key: "field1",
value: ["example1", "example2"]
}
}
]
});
条件科
在这个例子中 section1 区域及其所有嵌入字段的值 field1 实值 true。 。 。 .
createNodeDescriptor({
// ...
fields: [
// ... (field1)
],
sections: [
{
key: "section1",
// ...
condition: {
key: "field1",
value: true
}
}
]
});
否认
在这个例子中, field2 将仅显示在 field1 实值 没有 true。 。 。 .
createNodeDescriptor({
// ...
fields: [
// ... (field1)
{
key: "field2",
// ...
condition: {
key: "field1",
value: true,
negate: true
}
}
]
})
和运算符
在这个例子中, field3 仅在两者的值 field1 财务报告和审定财务报表 field2 设定为 true。 。 。 .
createNodeDescriptor({
// ...
fields: [
// ... (field1 and field2)
{
key: "field3",
// ...
condition: {
and: [
{
key: "field1",
value: true
},
{
key: "field2",
value: true
}
]
}
}
]
});
OR 运算符
在这个例子中, field3 仅在至少一个值为 field1 或者说 field2 设置为 true。 。 。 .
createNodeDescriptor({
// ...
fields: [
// ... (field1 and field2)
{
key: "field3",
// ...
condition: {
or: [
{
key: "field1",
value: true
},
{
key: "field2",
value: true
}
]
}
}
]
});
嵌入式运算符
在这个例子中, field4 仅显示于 field1 财务报告和审定财务报表 field2 都设定为 true 或如果 field3 设置为 true。 。 。 .
createNodeDescriptor({
// ...
fields: [
// ... (field1, field2 and field3)
{
key: "field4",
// ...
condition: {
or: [
{
and: [
{
key: "field1",
value: true
},
{
key: "field2",
value: true
}
]
},
{
key: "field3",
value: true
}
]
}
}
]
});
子节点
您可以使用儿童节点和 setNextNode API (英语). 例如,这用于 Lookup 财务报告和审定财务报表 If 节点.
下面的例子说明如何建立一个 random 节点和它的独家儿童节点类型, randomChild当执行时,它随机选择一个孩子,并继续在该儿童节点执行流刑.
createNodeDescriptor({
// ...
type: "random",
// pick a random configuration from one of its child Nodes
// and continue Flow execution there
function: async ({ childConfigs, cognigy }) => {
if (childConfigs.length > 0) {
const nextNode = childConfigs[Math.floor(Math.random() * childConfigs.length)]
cognigy.api.setNextNode(nextNode.id);
}
},
// only "randomChild" Nodes are allowed as children for this Node!
constraints: {
placement: {
children: {
whitelist: ["randomChild"]
}
}
},
// when this Node is created, two "randomChild" child Nodes
// will be created automatically
dependencies: {
children: ["randomChild", "randomChild"]
}
});
createNodeDescriptor({
// ...
type: "randomChild",
parentType: "random",
appearance: {
variant: "mini"
}
});
本地化
创建扩展(Creating Extensions)是进一步扩展具有额外功能的认知AI所需的重要功能. 由于UI支持菜单中的几种语言,我们还增加了一个功能来向扩展添加翻译.
本地化是一个完全可选的特点,可以在需要时使用. 不需要在整个扩展中一致执行,也可以使用它来翻译一个单一的字符串.
本地化
本地化是用Cognigy AI 4.1.20.版本推出的,因此需要升级到这个版本或后一个版本才能使用这个功能.
本地化对象
本地化支持用这样的 JSON 对象替换简单的字符串 :
{
"default": "Default fallback string",
"enUS": "String with English Localization",
"deDE": "String with German Localization",
"esES": "String with Spanish Localization",
"koKR": "String with Korean Localization",
"jaJP": "String with Japanese Localization"
}
这个 default 属性是强制性的,其他属性是可选的,因此可以选择只有英语和德语本地化.
本地化可见度
Cognigy.AI用户界面(UI)的每个用户都会看到本地化,因此,一个带有德文本地化的节点会用德文显示,每个用户的本地化设置为德文.
终端用户在与本地化的节点通信时不会看到任何区别.
本地化目标
本地化并不适用于所有属性. 现在这些属性在描述符中支持:
defaultLabelsummary
这些属性在一个节点部分得到支持 :
label
这些属性在一个节点字段中支持:
labeldescription
如果一个节点字段是“ 选择” 类型, 那么它也会在参数中选项的标签属性中支持
本地化示例
让我们来拿一个样本 描述器没有本地化:
export const mySampleNode = createNodeDescriptor({
type: "myExampleNode",
defaultLabel: "My example Node",
summary: "Just a simple example Node",
fields: [
{
key: "textInput",
label: "My Example Text Input",
type: "cognigyText",
},
{
key: "selectIcecream",
label: "Do you like Icecream?",
params: {
options: [
{
label: "Yes, I love Icecream!",
value: true
},
{
label: "No, I don't",
value: false
}
]
}
}
],
sections: [
{
key: "importantQuestions",
label: "Important Questions",
defaultCollapsed: true,
fields: [
"selectIcecream"
]
}
],
form: [
{ type: "field", key: "textInput" },
{ type: "section", key: "importantQuestions" }
],
function: async ({ cognigy, config }: IMySampleNode) => {
// my Node logic
}
})
增加一个德语译名可能是这样的:
export const mySampleNode = createNodeDescriptor({
type: "myExampleNode",
defaultLabel: {
default: "My example Node",
deDE: "Mein Beispiel Node"
},
summary: {
default: "Just a simple example Node",
deDE: "Nur ein einfaches Beispielnode"
},
fields: [
{
key: "textInput",
label: {
default: "My Example Text Input",
deDE: "Mein Beispiel Text Eingabefeld"
},
type: "cognigyText",
},
{
key: "selectIcecream",
label: {
default: "Do you like Icecream?",
deDE: "Magst du Eiscreme?"
},
params: {
options: [
{
label: {
default: "Yes, I love Icecream!",
deDE: "Ja, ich liebe Eiscreme!"
},
value: true
},
{
label: {
default: "No, I don't",
deDE: "Nein, ich mag es nicht"
},
value: false
}
]
}
}
],
sections: [
{
key: "importantQuestions",
label: {
default: "Important Questions",
deDE: "Wichtige Fragen"
},
defaultCollapsed: true,
fields: [
"selectIcecream"
]
}
],
form: [
{ type: "field", key: "textInput" },
{ type: "section", key: "importantQuestions" }
],
function: async ({ cognigy, config }: IMySampleNode) => {
// my Node logic
}
})
选项解析器
选项解析器是一种通过为节点球场提供动态解析选择选项来增强认知扩展与第三方系统的无缝整合的方法.
选项解析器可用性
Cognigy AI版本4.9.0引入了选项解析器,因此需要升级到此或后发版本才能使用此功能.
使用大小写
这个功能围绕的基准案例是让流程编辑用户在第三方系统上选择一个实际实体(例如其Dropbox上的文件) 它也可以在没有第三方系统的情况下被使用,例如根据其他的字段选择过滤出一组可用的选项(例如,如果设置了另一个"国家"字段,可以缩小到只显示来自某个国家的城市的城市的城市列表).
用法示例
下面的代码片段描述了一个"字段配置",其中包含一个选项解析器,它使所选字段显示一个文件列表,作为从第三方API中获取的选项.
它假设有一个HTTP API在 https://example.service/files 返回“文件”列表为 JSON,并要求设置认证头.
这个例子还假设另一个领域叫做 credentials 在这个节点。 这通常是一个"秘密".
“ Resolver 函数” 使用 API 的值从 API 获取文件列表 credentials 字段并返回为一系列选项.
const node = createNodeDescriptor({
// ...
fields: [
// ...
{
type: "select",
key: "file",
label: "File on Example Service",
optionsResolver: {
dependencies: ["credentials"],
resolverFunction: async ({ api, config }) => {
// fetch list of files using http request
const response = await api.httpRequest({
method: "GET",
url: `https://example.service/files`,
headers: {
xApiKey: config.credentials.apiKey,
},
});
// map file list to "options array"
return response.map((file) => {
return {
label: file.basename,
value: file.path,
};
});
},
},
},
],
});
API 参考
选项解析器
这个 optionsResolver 配置只能设置在带有类型的节点字段上 select 目前为止.
选项解析依赖
这个 dependencies 阵列中包含一个列表,列出用于实现 resolverFunction。通常,这将包括一个“秘密领域”的密钥,那里有API的认证证书.
所有注册的依赖字段值都将提供给 resolverFunction 作为对象映射( e){ [fieldKey]: fieldValue }) (中文(简体) ).
解析器函数
这个 resolverFunction 用于解决选定字段的新选项。 它将从节点编辑器被触发,但在后端被执行.
依赖和触发
这个 resolverFunction 有机会进入 config 对象,包含所有已注册的依赖字段的密钥值映射(见上文节).
每次在节点编辑器中更改注册依赖字段时 resolverFunction 将随新的值(包括中间的、非保存的更改!)而被触发.
已解析的选项验证
这个 resolverFunction 返回精确形状为:
interface IResolvedOption {
label: string;
value: string;
}
返回的值 resolverFunction 将使用一个方案验证。 如果不符合上述"可选舍马",则不会还原任何选项.
API & HTTP 请求
这个 resolverFunction 会得到一个 api 作为参数的对象.
您将可以使用 api.httpRequest。 。 。 .
这个 httpRequest 函数将尊重为认知配置的代理配置。 您正在运行的 AI 安装 .