add authentication support
This commit is contained in:
51
dist/auth/JLINCAuthBaseChatModel.d.ts
vendored
Normal file
51
dist/auth/JLINCAuthBaseChatModel.d.ts
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
export type JLINCConfig = import("./common").JLINCConfig;
|
||||
export type JLINCAuthBaseChatModelFields = {
|
||||
config: JLINCConfig;
|
||||
jlincAuthDecision: Tool;
|
||||
targetAuthorized: BaseChatModel;
|
||||
targetNotAuthorized: BaseChatModel | null;
|
||||
};
|
||||
/**
|
||||
* @typedef {import('./common').JLINCConfig} JLINCConfig
|
||||
*/
|
||||
/**
|
||||
* @typedef {Object} JLINCAuthBaseChatModelFields
|
||||
* @property {JLINCConfig} config
|
||||
* @property {Tool} jlincAuthDecision
|
||||
* @property {BaseChatModel} targetAuthorized
|
||||
* @property {BaseChatModel|null} targetNotAuthorized
|
||||
*/
|
||||
export class JLINCAuthBaseChatModel extends BaseChatModel<import("@langchain/core/language_models/chat_models").BaseChatModelCallOptions, import("@langchain/core/dist/messages/ai.js").AIMessageChunk> {
|
||||
/**
|
||||
* @param {JLINCAuthBaseChatModelFields} fields
|
||||
*/
|
||||
constructor({ config, jlincAuthDecision, targetAuthorized, targetNotAuthorized }: JLINCAuthBaseChatModelFields);
|
||||
/** @type {JLINCConfig} */
|
||||
config: JLINCConfig;
|
||||
/** @type {Tool} */
|
||||
jlincAuthDecision: Tool;
|
||||
/** @type {BaseChatModel} */
|
||||
targetAuthorized: BaseChatModel;
|
||||
/** @type {BaseChatModel|null} */
|
||||
targetNotAuthorized: BaseChatModel | null;
|
||||
/** @type {JLINCTracer} */
|
||||
tracer: JLINCTracer;
|
||||
/** @type {string} */
|
||||
authType: string;
|
||||
/**
|
||||
* @param {BindToolsInput[]} tools - The tools to bind to the underlying models.
|
||||
* @param {Partial<CallOptions>} [kwargs] - Optional call options.
|
||||
* @returns {Runnable<BaseLanguageModelInput, OutputMessageType, CallOptions>}
|
||||
* A new JLINCAuthBaseChatModel instance whose underlying models
|
||||
* have been bound with the provided tools.
|
||||
*/
|
||||
bindTools(tools: BindToolsInput[], kwargs?: Partial<CallOptions>): Runnable<BaseLanguageModelInput, OutputMessageType, CallOptions>;
|
||||
/**
|
||||
* @param {BaseLanguageModelInput} input
|
||||
* @param {Partial<CallOptions>} [options] - Optional call options.
|
||||
* @returns {Promise<OutputMessageType>} A promise that resolves with the output.
|
||||
*/
|
||||
invoke(input: BaseLanguageModelInput, runManager: any): Promise<OutputMessageType>;
|
||||
}
|
||||
import { BaseChatModel } from "@langchain/core/dist/language_models/chat_models.js";
|
||||
import { JLINCTracer } from "../tracer/index.js";
|
||||
96
dist/auth/JLINCAuthBaseChatModel.js
vendored
Normal file
96
dist/auth/JLINCAuthBaseChatModel.js
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
const { BaseChatModel } = require("@langchain/core/language_models/chat_models");
|
||||
const { JLINCTracer } = require("../tracer/index.js");
|
||||
const { authDecide, authInvoke, getDescription, getName } = require("./common.js");
|
||||
|
||||
/**
|
||||
* @typedef {import('./common').JLINCConfig} JLINCConfig
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} JLINCAuthBaseChatModelFields
|
||||
* @property {JLINCConfig} config
|
||||
* @property {Tool} jlincAuthDecision
|
||||
* @property {BaseChatModel} targetAuthorized
|
||||
* @property {BaseChatModel|null} targetNotAuthorized
|
||||
*/
|
||||
|
||||
class JLINCAuthBaseChatModel extends BaseChatModel {
|
||||
/**
|
||||
* @param {JLINCAuthBaseChatModelFields} fields
|
||||
*/
|
||||
constructor({ config, jlincAuthDecision, targetAuthorized, targetNotAuthorized }) {
|
||||
super({
|
||||
name: "jlinc_auth_base_chat_model",
|
||||
description: "", // overridden dynamically
|
||||
});
|
||||
Object.defineProperty(this, "name", {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true,
|
||||
value: getName(targetAuthorized, targetNotAuthorized)
|
||||
});
|
||||
Object.defineProperty(this, "description", {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true,
|
||||
value: getDescription(targetAuthorized, targetNotAuthorized, 'BaseChatModel')
|
||||
});
|
||||
/** @type {JLINCConfig} */
|
||||
this.config = config;
|
||||
/** @type {Tool} */
|
||||
this.jlincAuthDecision = jlincAuthDecision;
|
||||
/** @type {BaseChatModel} */
|
||||
this.targetAuthorized = targetAuthorized;
|
||||
/** @type {BaseChatModel|null} */
|
||||
this.targetNotAuthorized = targetNotAuthorized;
|
||||
/** @type {JLINCTracer} */
|
||||
this.tracer = new JLINCTracer(config);
|
||||
/** @type {string} */
|
||||
this.authType = 'BaseChatModel';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {BindToolsInput[]} tools - The tools to bind to the underlying models.
|
||||
* @param {Partial<CallOptions>} [kwargs] - Optional call options.
|
||||
* @returns {Runnable<BaseLanguageModelInput, OutputMessageType, CallOptions>}
|
||||
* A new JLINCAuthBaseChatModel instance whose underlying models
|
||||
* have been bound with the provided tools.
|
||||
*/
|
||||
bindTools(tools, kwargs = {}) {
|
||||
if (this.config.debug)
|
||||
console.log(`[JLINCAuth] Binding tools to BaseChatModels`);
|
||||
const authorizedBound = this.targetAuthorized.bindTools(tools, kwargs);
|
||||
const notAuthorizedBound = this.targetNotAuthorized
|
||||
? this.targetNotAuthorized.bindTools(tools, kwargs)
|
||||
: null;
|
||||
return new JLINCAuthBaseChatModel({
|
||||
config: this.config,
|
||||
jlincAuthDecision: this.jlincAuthDecision,
|
||||
targetAuthorized: authorizedBound,
|
||||
targetNotAuthorized: notAuthorizedBound,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string} - type
|
||||
*/
|
||||
_llmType() {
|
||||
const type = this.targetAuthorized?._llmType?.() ?? "unknown";
|
||||
if (this.config?.debug)
|
||||
console.log(`[JLINCAuth] Returning LLM type: ${type}`);
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {BaseLanguageModelInput} input
|
||||
* @param {Partial<CallOptions>} [options] - Optional call options.
|
||||
* @returns {Promise<OutputMessageType>} A promise that resolves with the output.
|
||||
*/
|
||||
async invoke(input, runManager) {
|
||||
return await authInvoke(this, input);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
JLINCAuthBaseChatModel,
|
||||
};
|
||||
29
dist/auth/JLINCAuthDecision.d.ts
vendored
Normal file
29
dist/auth/JLINCAuthDecision.d.ts
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
export type JLINCConfig = import("./common").JLINCConfig;
|
||||
/**
|
||||
* @typedef {import('./common').JLINCConfig} JLINCConfig
|
||||
*/
|
||||
export class JLINCAuthDecision extends Tool<any> {
|
||||
/**
|
||||
* @param {JLINCConfig} fields
|
||||
*/
|
||||
constructor(config: any);
|
||||
/** @type {JLINCConfig} */
|
||||
config: JLINCConfig;
|
||||
/** @type {Boolean} */
|
||||
authenticated: boolean;
|
||||
/**
|
||||
* @param {any} payload
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
postToApi(auth: any): Promise<any>;
|
||||
/**
|
||||
* @param {auth} auth
|
||||
* @returns {Promise<boolean>} - authenticated
|
||||
*/
|
||||
evaluate(auth: any): Promise<boolean>;
|
||||
/**
|
||||
* @returns {boolean} - authenticated
|
||||
*/
|
||||
getAuth(): boolean;
|
||||
}
|
||||
import { Tool } from "@langchain/core/dist/tools";
|
||||
79
dist/auth/JLINCAuthDecision.js
vendored
Normal file
79
dist/auth/JLINCAuthDecision.js
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
const { Tool } = require("@langchain/core/tools");
|
||||
const axios = require("axios");
|
||||
|
||||
/**
|
||||
* @typedef {import('./common').JLINCConfig} JLINCConfig
|
||||
*/
|
||||
|
||||
class JLINCAuthDecision extends Tool {
|
||||
/**
|
||||
* @param {JLINCConfig} fields
|
||||
*/
|
||||
constructor(config) {
|
||||
super({
|
||||
name: "jlinc_auth",
|
||||
description: "Authorization via AuthZEN format.",
|
||||
});
|
||||
Object.defineProperty(this, "name", {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true,
|
||||
value: "jlinc-auth"
|
||||
});
|
||||
Object.defineProperty(this, "description", {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true,
|
||||
value: "Authorization via AuthZEN format."
|
||||
});
|
||||
/** @type {JLINCConfig} */
|
||||
this.config = config;
|
||||
/** @type {Boolean} */
|
||||
this.authenticated = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {any} payload
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
async postToApi(auth) {
|
||||
const response = await axios.post(
|
||||
`${this.config.dataStoreApiUrl}/api/v1/auth`,
|
||||
auth,
|
||||
{
|
||||
headers: {
|
||||
'Authorization': `Bearer ${this.config.dataStoreApiKey}`,
|
||||
}
|
||||
}
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {auth} auth
|
||||
* @returns {Promise<boolean>} - authenticated
|
||||
*/
|
||||
async evaluate(auth) {
|
||||
this.authenticated = false;
|
||||
try {
|
||||
this.authenticated = (await this.postToApi(auth)).decision;
|
||||
} catch (e) {
|
||||
console.log(`[JLINCAuthTool] Error connecting to API, flagging as unauthorized`);
|
||||
if (this.config.debug) console.error(e)
|
||||
}
|
||||
if (this.config.debug)
|
||||
console.log(`[JLINCAuth] Got authorization of: ${this.authenticated}`);
|
||||
return this.authenticated;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {boolean} - authenticated
|
||||
*/
|
||||
getAuth() {
|
||||
return this.authenticated;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
JLINCAuthDecision,
|
||||
};
|
||||
47
dist/auth/JLINCAuthTool.d.ts
vendored
Normal file
47
dist/auth/JLINCAuthTool.d.ts
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
export type JLINCConfig = import("./common").JLINCConfig;
|
||||
export type JLINCAuthToolFields = {
|
||||
config: JLINCConfig;
|
||||
jlincAuthDecision: Tool;
|
||||
targetAuthorized: Tool;
|
||||
targetNotAuthorized: Tool | null;
|
||||
};
|
||||
/**
|
||||
* @typedef {import('./common').JLINCConfig} JLINCConfig
|
||||
*/
|
||||
/**
|
||||
* @typedef {Object} JLINCAuthToolFields
|
||||
* @property {JLINCConfig} config
|
||||
* @property {Tool} jlincAuthDecision
|
||||
* @property {Tool} targetAuthorized
|
||||
* @property {Tool|null} targetNotAuthorized
|
||||
*/
|
||||
export class JLINCAuthTool extends Tool<any> {
|
||||
/**
|
||||
* @param {JLINCAuthToolFields} fields
|
||||
*/
|
||||
constructor({ config, jlincAuthDecision, targetAuthorized, targetNotAuthorized }: JLINCAuthToolFields);
|
||||
/** @type {JLINCConfig} */
|
||||
config: JLINCConfig;
|
||||
/** @type {Tool} */
|
||||
jlincAuthDecision: Tool;
|
||||
/** @type {Tool} */
|
||||
targetAuthorized: Tool;
|
||||
/** @type {Tool|null} */
|
||||
targetNotAuthorized: Tool | null;
|
||||
/** @type {JLINCTracer} */
|
||||
tracer: JLINCTracer;
|
||||
/** @type {string} */
|
||||
authType: string;
|
||||
/**
|
||||
* @template TInput
|
||||
* @template {undefined | ToolRunnableConfig} TConfig
|
||||
* @template TOutput
|
||||
*
|
||||
* @param {TInput} input
|
||||
* @param {TConfig} [config]
|
||||
* @returns {Promise<ToolReturnType<TInput, TConfig, TOutput>>}
|
||||
*/
|
||||
invoke<TInput, TConfig extends undefined | ToolRunnableConfig, TOutput>(input: TInput, runManager: any): Promise<ToolReturnType<TInput, TConfig, TOutput>>;
|
||||
}
|
||||
import { Tool } from "@langchain/core/dist/tools/index.js";
|
||||
import { JLINCTracer } from "../tracer/index.js";
|
||||
68
dist/auth/JLINCAuthTool.js
vendored
Normal file
68
dist/auth/JLINCAuthTool.js
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
const { Tool } = require("@langchain/core/tools");
|
||||
const { JLINCTracer } = require("../tracer/index.js");
|
||||
const { authDecide, authInvoke, getDescription, getName } = require("./common.js");
|
||||
|
||||
/**
|
||||
* @typedef {import('./common').JLINCConfig} JLINCConfig
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} JLINCAuthToolFields
|
||||
* @property {JLINCConfig} config
|
||||
* @property {Tool} jlincAuthDecision
|
||||
* @property {Tool} targetAuthorized
|
||||
* @property {Tool|null} targetNotAuthorized
|
||||
*/
|
||||
|
||||
class JLINCAuthTool extends Tool {
|
||||
/**
|
||||
* @param {JLINCAuthToolFields} fields
|
||||
*/
|
||||
constructor({ config, jlincAuthDecision, targetAuthorized, targetNotAuthorized }) {
|
||||
super({
|
||||
name: "jlinc_auth_tool",
|
||||
description: "", // overridden dynamically
|
||||
});
|
||||
Object.defineProperty(this, "name", {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true,
|
||||
value: getName(targetAuthorized, targetNotAuthorized)
|
||||
});
|
||||
Object.defineProperty(this, "description", {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true,
|
||||
value: getDescription(targetAuthorized, targetNotAuthorized, 'Tool')
|
||||
});
|
||||
/** @type {JLINCConfig} */
|
||||
this.config = config;
|
||||
/** @type {Tool} */
|
||||
this.jlincAuthDecision = jlincAuthDecision;
|
||||
/** @type {Tool} */
|
||||
this.targetAuthorized = targetAuthorized;
|
||||
/** @type {Tool|null} */
|
||||
this.targetNotAuthorized = targetNotAuthorized;
|
||||
/** @type {JLINCTracer} */
|
||||
this.tracer = new JLINCTracer(config);
|
||||
/** @type {string} */
|
||||
this.authType = 'Tool';
|
||||
}
|
||||
|
||||
/**
|
||||
* @template TInput
|
||||
* @template {undefined | ToolRunnableConfig} TConfig
|
||||
* @template TOutput
|
||||
*
|
||||
* @param {TInput} input
|
||||
* @param {TConfig} [config]
|
||||
* @returns {Promise<ToolReturnType<TInput, TConfig, TOutput>>}
|
||||
*/
|
||||
async invoke(input, runManager) {
|
||||
return await authInvoke(this, input);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
JLINCAuthTool,
|
||||
};
|
||||
37
dist/auth/common.d.ts
vendored
Normal file
37
dist/auth/common.d.ts
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
export type JLINCConfig = {
|
||||
dataStoreApiUrl?: string | undefined;
|
||||
dataStoreApiKey?: string | undefined;
|
||||
archiveApiUrl?: string | undefined;
|
||||
archiveApiKey?: string | undefined;
|
||||
systemPrefix?: string | undefined;
|
||||
agreementId?: string | null | undefined;
|
||||
debug?: boolean | undefined;
|
||||
};
|
||||
/**
|
||||
* @param {any} settings
|
||||
* @param {any} input
|
||||
* @returns {Promise<any>} - The result of invoking the selected tool.
|
||||
*/
|
||||
export function authInvoke(settings: any, input: any): Promise<any>;
|
||||
/**
|
||||
* @param {any} - Authorized
|
||||
* @param {any|null} - NotAuthorized
|
||||
* @returns {string} - The description
|
||||
*/
|
||||
export function getDescription(authorized: any, unauthorized: any, type: any): string;
|
||||
/**
|
||||
* @typedef {Object} JLINCConfig
|
||||
* @property {string} [dataStoreApiUrl]
|
||||
* @property {string} [dataStoreApiKey]
|
||||
* @property {string} [archiveApiUrl]
|
||||
* @property {string} [archiveApiKey]
|
||||
* @property {string} [systemPrefix]
|
||||
* @property {string|null} [agreementId]
|
||||
* @property {boolean} [debug]
|
||||
*/
|
||||
/**
|
||||
* @param {any} - Authorized
|
||||
* @param {any|null} - NotAuthorized
|
||||
* @returns {string} - The description
|
||||
*/
|
||||
export function getName(authorized: any, unauthorized: any): string;
|
||||
85
dist/auth/common.js
vendored
Normal file
85
dist/auth/common.js
vendored
Normal file
@@ -0,0 +1,85 @@
|
||||
const axios = require("axios");
|
||||
|
||||
/**
|
||||
* @typedef {Object} JLINCConfig
|
||||
* @property {string} [dataStoreApiUrl]
|
||||
* @property {string} [dataStoreApiKey]
|
||||
* @property {string} [archiveApiUrl]
|
||||
* @property {string} [archiveApiKey]
|
||||
* @property {string} [systemPrefix]
|
||||
* @property {string|null} [agreementId]
|
||||
* @property {boolean} [debug]
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {any} - Authorized
|
||||
* @param {any|null} - NotAuthorized
|
||||
* @returns {string} - The description
|
||||
*/
|
||||
function getName(authorized, unauthorized) {
|
||||
return unauthorized
|
||||
? `${authorized.name}-or-${unauthorized.name}`
|
||||
: `authorized-${authorized.name}`
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {any} - Authorized
|
||||
* @param {any|null} - NotAuthorized
|
||||
* @returns {string} - The description
|
||||
*/
|
||||
function getDescription(authorized, unauthorized, type) {
|
||||
return unauthorized ? `
|
||||
This is an authorization router ${type}. It decides whether
|
||||
to route input to an "authorized" or "not authorized" ${type}.
|
||||
|
||||
Authorized ${type}: ${authorized.name}
|
||||
Description: ${authorized.description}
|
||||
|
||||
Not Authorized ${type}: ${unauthorized.name}
|
||||
Description: ${unauthorized.description}
|
||||
|
||||
The LLM can assume both ${type}s are available, but JLINC Auth will
|
||||
only allow the Authorized ${type} to be called if you are authorized.
|
||||
` : `
|
||||
This is an authorization router ${type}. It decides whether
|
||||
to route input to an "authorized" ${type}.
|
||||
|
||||
Authorized ${type}: ${authorized.name}
|
||||
Description: ${authorized.description}
|
||||
|
||||
The LLM can assume the ${type} is available, but JLINC Auth will
|
||||
only allow the Authorized ${type} to be called if you are authorized.
|
||||
`
|
||||
}
|
||||
|
||||
function getLogName(target) {
|
||||
if (target.name) return target.name;
|
||||
if (target.lc_kwargs?.bound?.model) return target.lc_kwargs.bound.model;
|
||||
return 'no-name';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {any} settings
|
||||
* @param {any} input
|
||||
* @returns {Promise<any>} - The result of invoking the selected tool.
|
||||
*/
|
||||
async function authInvoke(settings, input) {
|
||||
const authorized = await settings.jlincAuthDecision.getAuth();
|
||||
let selectedTarget = settings.targetNotAuthorized
|
||||
if (authorized) {
|
||||
selectedTarget = settings.targetAuthorized
|
||||
}
|
||||
if (!selectedTarget)
|
||||
throw new Error("No valid resource available");
|
||||
if (settings.config.debug)
|
||||
console.log(`[JLINCAuth] Invoking ${getLogName(selectedTarget)} (${settings.authType}|${authorized})`);
|
||||
return await selectedTarget.invoke(input, {
|
||||
callbacks: [settings.tracer],
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
authInvoke,
|
||||
getDescription,
|
||||
getName,
|
||||
};
|
||||
4
dist/auth/index.d.ts
vendored
Normal file
4
dist/auth/index.d.ts
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
import { JLINCAuthDecision } from "./JLINCAuthDecision.js";
|
||||
import { JLINCAuthBaseChatModel } from "./JLINCAuthBaseChatModel.js";
|
||||
import { JLINCAuthTool } from "./JLINCAuthTool.js";
|
||||
export { JLINCAuthDecision, JLINCAuthBaseChatModel, JLINCAuthTool };
|
||||
9
dist/auth/index.js
vendored
Normal file
9
dist/auth/index.js
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
const { JLINCAuthDecision } = require("./JLINCAuthDecision.js");
|
||||
const { JLINCAuthBaseChatModel } = require("./JLINCAuthBaseChatModel.js");
|
||||
const { JLINCAuthTool } = require("./JLINCAuthTool.js");
|
||||
|
||||
module.exports = {
|
||||
JLINCAuthDecision,
|
||||
JLINCAuthBaseChatModel,
|
||||
JLINCAuthTool,
|
||||
};
|
||||
Reference in New Issue
Block a user