First upload version 0.0.1
This commit is contained in:
21
node_modules/@huggingface/jinja/LICENSE
generated
vendored
Normal file
21
node_modules/@huggingface/jinja/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2023 Hugging Face
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
78
node_modules/@huggingface/jinja/README.md
generated
vendored
Normal file
78
node_modules/@huggingface/jinja/README.md
generated
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
# Jinja
|
||||
|
||||
A minimalistic JavaScript implementation of the Jinja templating engine, specifically designed for parsing and rendering ML chat templates.
|
||||
|
||||
## Usage
|
||||
|
||||
### Load template from a model on the Hugging Face Hub
|
||||
|
||||
First, install the jinja and hub packages:
|
||||
|
||||
```sh
|
||||
npm i @huggingface/jinja
|
||||
npm i @huggingface/hub
|
||||
```
|
||||
|
||||
You can then load a tokenizer from the Hugging Face Hub and render a list of chat messages, as follows:
|
||||
|
||||
```js
|
||||
import { Template } from "@huggingface/jinja";
|
||||
import { downloadFile } from "@huggingface/hub";
|
||||
|
||||
const config = await (
|
||||
await downloadFile({
|
||||
repo: "mistralai/Mistral-7B-Instruct-v0.1",
|
||||
path: "tokenizer_config.json",
|
||||
})
|
||||
).json();
|
||||
|
||||
const chat = [
|
||||
{ role: "user", content: "Hello, how are you?" },
|
||||
{ role: "assistant", content: "I'm doing great. How can I help you today?" },
|
||||
{ role: "user", content: "I'd like to show off how chat templating works!" },
|
||||
];
|
||||
|
||||
const template = new Template(config.chat_template);
|
||||
const result = template.render({
|
||||
messages: chat,
|
||||
bos_token: config.bos_token,
|
||||
eos_token: config.eos_token,
|
||||
});
|
||||
// "<s>[INST] Hello, how are you? [/INST]I'm doing great. How can I help you today?</s> [INST] I'd like to show off how chat templating works! [/INST]"
|
||||
```
|
||||
|
||||
### Transformers.js
|
||||
|
||||
First, install `@huggingface/transformers`:
|
||||
|
||||
```sh
|
||||
npm i @huggingface/transformers
|
||||
```
|
||||
|
||||
You can then render a list of chat messages using a tokenizer's `apply_chat_template` method.
|
||||
|
||||
```js
|
||||
import { AutoTokenizer } from "@huggingface/transformers";
|
||||
|
||||
// Load tokenizer from the Hugging Face Hub
|
||||
const tokenizer = await AutoTokenizer.from_pretrained("mistralai/Mistral-7B-Instruct-v0.1");
|
||||
|
||||
// Define chat messages
|
||||
const chat = [
|
||||
{ role: "user", content: "Hello, how are you?" },
|
||||
{ role: "assistant", content: "I'm doing great. How can I help you today?" },
|
||||
{ role: "user", content: "I'd like to show off how chat templating works!" },
|
||||
];
|
||||
|
||||
const text = tokenizer.apply_chat_template(chat, { tokenize: false });
|
||||
// "<s>[INST] Hello, how are you? [/INST]I'm doing great. How can I help you today?</s> [INST] I'd like to show off how chat templating works! [/INST]"
|
||||
```
|
||||
|
||||
Notice how the entire chat is condensed into a single string. If you would instead like to return the tokenized version (i.e., a list of token IDs), you can use the following:
|
||||
|
||||
```js
|
||||
const input_ids = tokenizer.apply_chat_template(chat, { tokenize: true, return_tensor: false });
|
||||
// [1, 733, 16289, 28793, 22557, 28725, 910, 460, 368, 28804, 733, 28748, 16289, 28793, 28737, 28742, 28719, 2548, 1598, 28723, 1602, 541, 315, 1316, 368, 3154, 28804, 2, 28705, 733, 16289, 28793, 315, 28742, 28715, 737, 298, 1347, 805, 910, 10706, 5752, 1077, 3791, 28808, 733, 28748, 16289, 28793]
|
||||
```
|
||||
|
||||
For more information about chat templates, check out the transformers [documentation](https://huggingface.co/docs/transformers/main/en/chat_templating).
|
||||
221
node_modules/@huggingface/jinja/dist/ast.d.ts
generated
vendored
Normal file
221
node_modules/@huggingface/jinja/dist/ast.d.ts
generated
vendored
Normal file
@@ -0,0 +1,221 @@
|
||||
import type { Token } from "./lexer";
|
||||
/**
|
||||
* Statements do not result in a value at runtime. They contain one or more expressions internally.
|
||||
*/
|
||||
export declare class Statement {
|
||||
type: string;
|
||||
}
|
||||
/**
|
||||
* Defines a block which contains many statements. Each chat template corresponds to one Program.
|
||||
*/
|
||||
export declare class Program extends Statement {
|
||||
body: Statement[];
|
||||
type: string;
|
||||
constructor(body: Statement[]);
|
||||
}
|
||||
export declare class If extends Statement {
|
||||
test: Expression;
|
||||
body: Statement[];
|
||||
alternate: Statement[];
|
||||
type: string;
|
||||
constructor(test: Expression, body: Statement[], alternate: Statement[]);
|
||||
}
|
||||
/**
|
||||
* Loop over each item in a sequence
|
||||
* https://jinja.palletsprojects.com/en/3.0.x/templates/#for
|
||||
*/
|
||||
export declare class For extends Statement {
|
||||
loopvar: Identifier | TupleLiteral;
|
||||
iterable: Expression;
|
||||
body: Statement[];
|
||||
defaultBlock: Statement[];
|
||||
type: string;
|
||||
constructor(loopvar: Identifier | TupleLiteral, iterable: Expression, body: Statement[], defaultBlock: Statement[]);
|
||||
}
|
||||
export declare class Break extends Statement {
|
||||
type: string;
|
||||
}
|
||||
export declare class Continue extends Statement {
|
||||
type: string;
|
||||
}
|
||||
export declare class SetStatement extends Statement {
|
||||
assignee: Expression;
|
||||
value: Expression | null;
|
||||
body: Statement[];
|
||||
type: string;
|
||||
constructor(assignee: Expression, value: Expression | null, body: Statement[]);
|
||||
}
|
||||
export declare class Macro extends Statement {
|
||||
name: Identifier;
|
||||
args: Expression[];
|
||||
body: Statement[];
|
||||
type: string;
|
||||
constructor(name: Identifier, args: Expression[], body: Statement[]);
|
||||
}
|
||||
export declare class Comment extends Statement {
|
||||
value: string;
|
||||
type: string;
|
||||
constructor(value: string);
|
||||
}
|
||||
/**
|
||||
* Expressions will result in a value at runtime (unlike statements).
|
||||
*/
|
||||
export declare class Expression extends Statement {
|
||||
type: string;
|
||||
}
|
||||
export declare class MemberExpression extends Expression {
|
||||
object: Expression;
|
||||
property: Expression;
|
||||
computed: boolean;
|
||||
type: string;
|
||||
constructor(object: Expression, property: Expression, computed: boolean);
|
||||
}
|
||||
export declare class CallExpression extends Expression {
|
||||
callee: Expression;
|
||||
args: Expression[];
|
||||
type: string;
|
||||
constructor(callee: Expression, args: Expression[]);
|
||||
}
|
||||
/**
|
||||
* Represents a user-defined variable or symbol in the template.
|
||||
*/
|
||||
export declare class Identifier extends Expression {
|
||||
value: string;
|
||||
type: string;
|
||||
/**
|
||||
* @param {string} value The name of the identifier
|
||||
*/
|
||||
constructor(value: string);
|
||||
}
|
||||
/**
|
||||
* Abstract base class for all Literal expressions.
|
||||
* Should not be instantiated directly.
|
||||
*/
|
||||
declare abstract class Literal<T> extends Expression {
|
||||
value: T;
|
||||
type: string;
|
||||
constructor(value: T);
|
||||
}
|
||||
export declare class IntegerLiteral extends Literal<number> {
|
||||
type: string;
|
||||
}
|
||||
export declare class FloatLiteral extends Literal<number> {
|
||||
type: string;
|
||||
}
|
||||
/**
|
||||
* Represents a text constant in the template.
|
||||
*/
|
||||
export declare class StringLiteral extends Literal<string> {
|
||||
type: string;
|
||||
}
|
||||
/**
|
||||
* Represents an array literal in the template.
|
||||
*/
|
||||
export declare class ArrayLiteral extends Literal<Expression[]> {
|
||||
type: string;
|
||||
}
|
||||
/**
|
||||
* Represents a tuple literal in the template.
|
||||
*/
|
||||
export declare class TupleLiteral extends Literal<Expression[]> {
|
||||
type: string;
|
||||
}
|
||||
/**
|
||||
* Represents an object literal in the template.
|
||||
*/
|
||||
export declare class ObjectLiteral extends Literal<Map<Expression, Expression>> {
|
||||
type: string;
|
||||
}
|
||||
/**
|
||||
* An operation with two sides, separated by an operator.
|
||||
* Note: Either side can be a Complex Expression, with order
|
||||
* of operations being determined by the operator.
|
||||
*/
|
||||
export declare class BinaryExpression extends Expression {
|
||||
operator: Token;
|
||||
left: Expression;
|
||||
right: Expression;
|
||||
type: string;
|
||||
constructor(operator: Token, left: Expression, right: Expression);
|
||||
}
|
||||
/**
|
||||
* An operation with two sides, separated by the | operator.
|
||||
* Operator precedence: https://github.com/pallets/jinja/issues/379#issuecomment-168076202
|
||||
*/
|
||||
export declare class FilterExpression extends Expression {
|
||||
operand: Expression;
|
||||
filter: Identifier | CallExpression;
|
||||
type: string;
|
||||
constructor(operand: Expression, filter: Identifier | CallExpression);
|
||||
}
|
||||
export declare class FilterStatement extends Statement {
|
||||
filter: Identifier | CallExpression;
|
||||
body: Statement[];
|
||||
type: string;
|
||||
constructor(filter: Identifier | CallExpression, body: Statement[]);
|
||||
}
|
||||
/**
|
||||
* An operation which filters a sequence of objects by applying a test to each object,
|
||||
* and only selecting the objects with the test succeeding.
|
||||
*
|
||||
* It may also be used as a shortcut for a ternary operator.
|
||||
*/
|
||||
export declare class SelectExpression extends Expression {
|
||||
lhs: Expression;
|
||||
test: Expression;
|
||||
type: string;
|
||||
constructor(lhs: Expression, test: Expression);
|
||||
}
|
||||
/**
|
||||
* An operation with two sides, separated by the "is" operator.
|
||||
*/
|
||||
export declare class TestExpression extends Expression {
|
||||
operand: Expression;
|
||||
negate: boolean;
|
||||
test: Identifier;
|
||||
type: string;
|
||||
constructor(operand: Expression, negate: boolean, test: Identifier);
|
||||
}
|
||||
/**
|
||||
* An operation with one side (operator on the left).
|
||||
*/
|
||||
export declare class UnaryExpression extends Expression {
|
||||
operator: Token;
|
||||
argument: Expression;
|
||||
type: string;
|
||||
constructor(operator: Token, argument: Expression);
|
||||
}
|
||||
export declare class SliceExpression extends Expression {
|
||||
start: Expression | undefined;
|
||||
stop: Expression | undefined;
|
||||
step: Expression | undefined;
|
||||
type: string;
|
||||
constructor(start?: Expression | undefined, stop?: Expression | undefined, step?: Expression | undefined);
|
||||
}
|
||||
export declare class KeywordArgumentExpression extends Expression {
|
||||
key: Identifier;
|
||||
value: Expression;
|
||||
type: string;
|
||||
constructor(key: Identifier, value: Expression);
|
||||
}
|
||||
export declare class SpreadExpression extends Expression {
|
||||
argument: Expression;
|
||||
type: string;
|
||||
constructor(argument: Expression);
|
||||
}
|
||||
export declare class CallStatement extends Statement {
|
||||
call: CallExpression;
|
||||
callerArgs: Expression[] | null;
|
||||
body: Statement[];
|
||||
type: string;
|
||||
constructor(call: CallExpression, callerArgs: Expression[] | null, body: Statement[]);
|
||||
}
|
||||
export declare class Ternary extends Expression {
|
||||
condition: Expression;
|
||||
trueExpr: Expression;
|
||||
falseExpr: Expression;
|
||||
type: string;
|
||||
constructor(condition: Expression, trueExpr: Expression, falseExpr: Expression);
|
||||
}
|
||||
export {};
|
||||
//# sourceMappingURL=ast.d.ts.map
|
||||
1
node_modules/@huggingface/jinja/dist/ast.d.ts.map
generated
vendored
Normal file
1
node_modules/@huggingface/jinja/dist/ast.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"ast.d.ts","sourceRoot":"","sources":["../src/ast.ts"],"names":[],"mappings":"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"}
|
||||
3
node_modules/@huggingface/jinja/dist/format.d.ts
generated
vendored
Normal file
3
node_modules/@huggingface/jinja/dist/format.d.ts
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
import type { Program } from "./ast";
|
||||
export declare function format(program: Program, indent?: string | number): string;
|
||||
//# sourceMappingURL=format.d.ts.map
|
||||
1
node_modules/@huggingface/jinja/dist/format.d.ts.map
generated
vendored
Normal file
1
node_modules/@huggingface/jinja/dist/format.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,OAAO,EA4BP,MAAM,OAAO,CAAC;AAsBf,wBAAgB,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,GAAE,MAAM,GAAG,MAAa,GAAG,MAAM,CAI/E"}
|
||||
2857
node_modules/@huggingface/jinja/dist/index.cjs
generated
vendored
Normal file
2857
node_modules/@huggingface/jinja/dist/index.cjs
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
29
node_modules/@huggingface/jinja/dist/index.d.ts
generated
vendored
Normal file
29
node_modules/@huggingface/jinja/dist/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* @file Jinja templating engine
|
||||
*
|
||||
* A minimalistic JavaScript reimplementation of the [Jinja](https://github.com/pallets/jinja) templating engine,
|
||||
* to support the chat templates. Special thanks to [Tyler Laceby](https://github.com/tlaceby) for his amazing
|
||||
* ["Guide to Interpreters"](https://github.com/tlaceby/guide-to-interpreters-series) tutorial series,
|
||||
* which provided the basis for this implementation.
|
||||
*
|
||||
* See the [Transformers documentation](https://huggingface.co/docs/transformers/main/en/chat_templating) for more information.
|
||||
*
|
||||
* @module index
|
||||
*/
|
||||
import { tokenize } from "./lexer";
|
||||
import { parse } from "./parser";
|
||||
import { Environment, Interpreter } from "./runtime";
|
||||
import type { Program } from "./ast";
|
||||
export declare class Template {
|
||||
parsed: Program;
|
||||
/**
|
||||
* @param {string} template The template string
|
||||
*/
|
||||
constructor(template: string);
|
||||
render(items?: Record<string, unknown>): string;
|
||||
format(options?: {
|
||||
indent: string | number;
|
||||
}): string;
|
||||
}
|
||||
export { Environment, Interpreter, tokenize, parse };
|
||||
//# sourceMappingURL=index.d.ts.map
|
||||
1
node_modules/@huggingface/jinja/dist/index.d.ts.map
generated
vendored
Normal file
1
node_modules/@huggingface/jinja/dist/index.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACjC,OAAO,EAAE,WAAW,EAAE,WAAW,EAAgB,MAAM,WAAW,CAAC;AACnE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAIrC,qBAAa,QAAQ;IACpB,MAAM,EAAE,OAAO,CAAC;IAEhB;;OAEG;gBACS,QAAQ,EAAE,MAAM;IAQ5B,MAAM,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM;IAkB/C,MAAM,CAAC,OAAO,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,GAAG,MAAM;CAGrD;AAED,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC"}
|
||||
2826
node_modules/@huggingface/jinja/dist/index.js
generated
vendored
Normal file
2826
node_modules/@huggingface/jinja/dist/index.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
53
node_modules/@huggingface/jinja/dist/lexer.d.ts
generated
vendored
Normal file
53
node_modules/@huggingface/jinja/dist/lexer.d.ts
generated
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
* Represents tokens that our language understands in parsing.
|
||||
*/
|
||||
export declare const TOKEN_TYPES: Readonly<{
|
||||
Text: "Text";
|
||||
NumericLiteral: "NumericLiteral";
|
||||
StringLiteral: "StringLiteral";
|
||||
Identifier: "Identifier";
|
||||
Equals: "Equals";
|
||||
OpenParen: "OpenParen";
|
||||
CloseParen: "CloseParen";
|
||||
OpenStatement: "OpenStatement";
|
||||
CloseStatement: "CloseStatement";
|
||||
OpenExpression: "OpenExpression";
|
||||
CloseExpression: "CloseExpression";
|
||||
OpenSquareBracket: "OpenSquareBracket";
|
||||
CloseSquareBracket: "CloseSquareBracket";
|
||||
OpenCurlyBracket: "OpenCurlyBracket";
|
||||
CloseCurlyBracket: "CloseCurlyBracket";
|
||||
Comma: "Comma";
|
||||
Dot: "Dot";
|
||||
Colon: "Colon";
|
||||
Pipe: "Pipe";
|
||||
CallOperator: "CallOperator";
|
||||
AdditiveBinaryOperator: "AdditiveBinaryOperator";
|
||||
MultiplicativeBinaryOperator: "MultiplicativeBinaryOperator";
|
||||
ComparisonBinaryOperator: "ComparisonBinaryOperator";
|
||||
UnaryOperator: "UnaryOperator";
|
||||
Comment: "Comment";
|
||||
}>;
|
||||
export type TokenType = keyof typeof TOKEN_TYPES;
|
||||
/**
|
||||
* Represents a single token in the template.
|
||||
*/
|
||||
export declare class Token {
|
||||
value: string;
|
||||
type: TokenType;
|
||||
/**
|
||||
* Constructs a new Token.
|
||||
* @param {string} value The raw value as seen inside the source code.
|
||||
* @param {TokenType} type The type of token.
|
||||
*/
|
||||
constructor(value: string, type: TokenType);
|
||||
}
|
||||
export interface PreprocessOptions {
|
||||
trim_blocks?: boolean;
|
||||
lstrip_blocks?: boolean;
|
||||
}
|
||||
/**
|
||||
* Generate a list of tokens from a source string.
|
||||
*/
|
||||
export declare function tokenize(source: string, options?: PreprocessOptions): Token[];
|
||||
//# sourceMappingURL=lexer.d.ts.map
|
||||
1
node_modules/@huggingface/jinja/dist/lexer.d.ts.map
generated
vendored
Normal file
1
node_modules/@huggingface/jinja/dist/lexer.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"lexer.d.ts","sourceRoot":"","sources":["../src/lexer.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;EA4BtB,CAAC;AAEH,MAAM,MAAM,SAAS,GAAG,MAAM,OAAO,WAAW,CAAC;AAEjD;;GAEG;AACH,qBAAa,KAAK;IAOT,KAAK,EAAE,MAAM;IACb,IAAI,EAAE,SAAS;IAPvB;;;;OAIG;gBAEK,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,SAAS;CAEvB;AAgED,MAAM,WAAW,iBAAiB;IACjC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,aAAa,CAAC,EAAE,OAAO,CAAC;CACxB;AA8BD;;GAEG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,iBAAsB,GAAG,KAAK,EAAE,CAqPjF"}
|
||||
8
node_modules/@huggingface/jinja/dist/parser.d.ts
generated
vendored
Normal file
8
node_modules/@huggingface/jinja/dist/parser.d.ts
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
import { Token } from "./lexer";
|
||||
import { Program } from "./ast";
|
||||
/**
|
||||
* Generate the Abstract Syntax Tree (AST) from a list of tokens.
|
||||
* Operator precedence can be found here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_precedence#table
|
||||
*/
|
||||
export declare function parse(tokens: Token[]): Program;
|
||||
//# sourceMappingURL=parser.d.ts.map
|
||||
1
node_modules/@huggingface/jinja/dist/parser.d.ts.map
generated
vendored
Normal file
1
node_modules/@huggingface/jinja/dist/parser.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAe,MAAM,SAAS,CAAC;AAG7C,OAAO,EACN,OAAO,EA4BP,MAAM,OAAO,CAAC;AAEf;;;GAGG;AACH,wBAAgB,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,CAunB9C"}
|
||||
201
node_modules/@huggingface/jinja/dist/runtime.d.ts
generated
vendored
Normal file
201
node_modules/@huggingface/jinja/dist/runtime.d.ts
generated
vendored
Normal file
@@ -0,0 +1,201 @@
|
||||
import type { Statement, Program } from "./ast";
|
||||
export type AnyRuntimeValue = IntegerValue | FloatValue | StringValue | BooleanValue | ObjectValue | ArrayValue | FunctionValue | NullValue | UndefinedValue;
|
||||
/**
|
||||
* Abstract base class for all Runtime values.
|
||||
* Should not be instantiated directly.
|
||||
*/
|
||||
declare abstract class RuntimeValue<T> {
|
||||
type: string;
|
||||
value: T;
|
||||
/**
|
||||
* A collection of built-in functions for this type.
|
||||
*/
|
||||
builtins: Map<string, AnyRuntimeValue>;
|
||||
/**
|
||||
* Creates a new RuntimeValue.
|
||||
*/
|
||||
constructor(value?: T);
|
||||
/**
|
||||
* Determines truthiness or falsiness of the runtime value.
|
||||
* This function should be overridden by subclasses if it has custom truthiness criteria.
|
||||
* @returns {BooleanValue} BooleanValue(true) if the value is truthy, BooleanValue(false) otherwise.
|
||||
*/
|
||||
__bool__(): BooleanValue;
|
||||
toString(): string;
|
||||
}
|
||||
/**
|
||||
* Represents an integer value at runtime.
|
||||
*/
|
||||
export declare class IntegerValue extends RuntimeValue<number> {
|
||||
type: string;
|
||||
}
|
||||
/**
|
||||
* Represents a float value at runtime.
|
||||
*/
|
||||
export declare class FloatValue extends RuntimeValue<number> {
|
||||
type: string;
|
||||
toString(): string;
|
||||
}
|
||||
/**
|
||||
* Represents a string value at runtime.
|
||||
*/
|
||||
export declare class StringValue extends RuntimeValue<string> {
|
||||
type: string;
|
||||
builtins: Map<string, AnyRuntimeValue>;
|
||||
}
|
||||
/**
|
||||
* Represents a boolean value at runtime.
|
||||
*/
|
||||
export declare class BooleanValue extends RuntimeValue<boolean> {
|
||||
type: string;
|
||||
}
|
||||
/**
|
||||
* Represents an Object value at runtime.
|
||||
*/
|
||||
export declare class ObjectValue extends RuntimeValue<Map<string, AnyRuntimeValue>> {
|
||||
type: string;
|
||||
/**
|
||||
* NOTE: necessary to override since all JavaScript arrays are considered truthy,
|
||||
* while only non-empty Python arrays are consider truthy.
|
||||
*
|
||||
* e.g.,
|
||||
* - JavaScript: {} && 5 -> 5
|
||||
* - Python: {} and 5 -> {}
|
||||
*/
|
||||
__bool__(): BooleanValue;
|
||||
builtins: Map<string, AnyRuntimeValue>;
|
||||
items(): ArrayValue;
|
||||
keys(): ArrayValue;
|
||||
values(): ArrayValue;
|
||||
toString(): string;
|
||||
}
|
||||
/**
|
||||
* Represents a KeywordArguments value at runtime.
|
||||
*/
|
||||
export declare class KeywordArgumentsValue extends ObjectValue {
|
||||
type: string;
|
||||
}
|
||||
/**
|
||||
* Represents an Array value at runtime.
|
||||
*/
|
||||
export declare class ArrayValue extends RuntimeValue<AnyRuntimeValue[]> {
|
||||
type: string;
|
||||
builtins: Map<string, AnyRuntimeValue>;
|
||||
/**
|
||||
* NOTE: necessary to override since all JavaScript arrays are considered truthy,
|
||||
* while only non-empty Python arrays are consider truthy.
|
||||
*
|
||||
* e.g.,
|
||||
* - JavaScript: [] && 5 -> 5
|
||||
* - Python: [] and 5 -> []
|
||||
*/
|
||||
__bool__(): BooleanValue;
|
||||
toString(): string;
|
||||
}
|
||||
/**
|
||||
* Represents a Tuple value at runtime.
|
||||
* NOTE: We extend ArrayValue since JavaScript does not have a built-in Tuple type.
|
||||
*/
|
||||
export declare class TupleValue extends ArrayValue {
|
||||
type: string;
|
||||
}
|
||||
/**
|
||||
* Represents a Function value at runtime.
|
||||
*/
|
||||
export declare class FunctionValue extends RuntimeValue<(args: AnyRuntimeValue[], scope: Environment) => AnyRuntimeValue> {
|
||||
type: string;
|
||||
}
|
||||
/**
|
||||
* Represents a Null value at runtime.
|
||||
*/
|
||||
export declare class NullValue extends RuntimeValue<null> {
|
||||
type: string;
|
||||
}
|
||||
/**
|
||||
* Represents an Undefined value at runtime.
|
||||
*/
|
||||
export declare class UndefinedValue extends RuntimeValue<undefined> {
|
||||
type: string;
|
||||
}
|
||||
/**
|
||||
* Represents the current environment (scope) at runtime.
|
||||
*/
|
||||
export declare class Environment {
|
||||
parent?: Environment | undefined;
|
||||
/**
|
||||
* The variables declared in this environment.
|
||||
*/
|
||||
variables: Map<string, AnyRuntimeValue>;
|
||||
/**
|
||||
* The tests available in this environment.
|
||||
*/
|
||||
tests: Map<string, (...value: AnyRuntimeValue[]) => boolean>;
|
||||
constructor(parent?: Environment | undefined);
|
||||
/**
|
||||
* Set the value of a variable in the current environment.
|
||||
*/
|
||||
set(name: string, value: unknown): AnyRuntimeValue;
|
||||
private declareVariable;
|
||||
/**
|
||||
* Set variable in the current scope.
|
||||
* See https://jinja.palletsprojects.com/en/3.0.x/templates/#assignments for more information.
|
||||
*/
|
||||
setVariable(name: string, value: AnyRuntimeValue): AnyRuntimeValue;
|
||||
/**
|
||||
* Resolve the environment in which the variable is declared.
|
||||
* @param {string} name The name of the variable.
|
||||
* @returns {Environment} The environment in which the variable is declared.
|
||||
*/
|
||||
private resolve;
|
||||
lookupVariable(name: string): AnyRuntimeValue;
|
||||
}
|
||||
export declare function setupGlobals(env: Environment): void;
|
||||
export declare class Interpreter {
|
||||
global: Environment;
|
||||
constructor(env?: Environment);
|
||||
/**
|
||||
* Run the program.
|
||||
*/
|
||||
run(program: Program): AnyRuntimeValue;
|
||||
/**
|
||||
* Evaluates expressions following the binary operation type.
|
||||
*/
|
||||
private evaluateBinaryExpression;
|
||||
private evaluateArguments;
|
||||
private applyFilter;
|
||||
/**
|
||||
* Evaluates expressions following the filter operation type.
|
||||
*/
|
||||
private evaluateFilterExpression;
|
||||
/**
|
||||
* Evaluates expressions following the test operation type.
|
||||
*/
|
||||
private evaluateTestExpression;
|
||||
/**
|
||||
* Evaluates expressions following the select operation type.
|
||||
*/
|
||||
private evaluateSelectExpression;
|
||||
/**
|
||||
* Evaluates expressions following the unary operation type.
|
||||
*/
|
||||
private evaluateUnaryExpression;
|
||||
private evaluateTernaryExpression;
|
||||
private evalProgram;
|
||||
private evaluateBlock;
|
||||
private evaluateIdentifier;
|
||||
private evaluateCallExpression;
|
||||
private evaluateSliceExpression;
|
||||
private evaluateMemberExpression;
|
||||
private evaluateSet;
|
||||
private evaluateIf;
|
||||
private evaluateFor;
|
||||
/**
|
||||
* See https://jinja.palletsprojects.com/en/3.1.x/templates/#macros for more information.
|
||||
*/
|
||||
private evaluateMacro;
|
||||
private evaluateCallStatement;
|
||||
private evaluateFilterStatement;
|
||||
evaluate(statement: Statement | undefined, environment: Environment): AnyRuntimeValue;
|
||||
}
|
||||
export {};
|
||||
//# sourceMappingURL=runtime.d.ts.map
|
||||
1
node_modules/@huggingface/jinja/dist/runtime.d.ts.map
generated
vendored
Normal file
1
node_modules/@huggingface/jinja/dist/runtime.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"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"}
|
||||
33
node_modules/@huggingface/jinja/dist/utils.d.ts
generated
vendored
Normal file
33
node_modules/@huggingface/jinja/dist/utils.d.ts
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* Function that mimics Python's range() function.
|
||||
* @param start The start value of the range.
|
||||
* @param stop The stop value of the range. If not provided, start will be 0 and stop will be the provided start value.
|
||||
* @param step The step value of the range. Defaults to 1.
|
||||
* @returns The range of numbers.
|
||||
*/
|
||||
export declare function range(start: number, stop?: number, step?: number): number[];
|
||||
/**
|
||||
* Function that mimics Python's array slicing.
|
||||
* @param array The array to slice.
|
||||
* @param start The start index of the slice. Defaults to 0.
|
||||
* @param stop The last index of the slice. Defaults to `array.length`.
|
||||
* @param step The step value of the slice. Defaults to 1.
|
||||
* @returns The sliced array.
|
||||
*/
|
||||
export declare function slice<T>(array: T[], start?: number, stop?: number, step?: number): T[];
|
||||
/**
|
||||
* Function that mimics Python's string.title() function.
|
||||
* @param value The string to title case.
|
||||
* @returns The title cased string.
|
||||
*/
|
||||
export declare function titleCase(value: string): string;
|
||||
export declare function strftime_now(format: string): string;
|
||||
/**
|
||||
* A minimalistic implementation of Python's strftime function.
|
||||
*/
|
||||
export declare function strftime(date: Date, format: string): string;
|
||||
/**
|
||||
* Function that mimics Python's string.replace() function.
|
||||
*/
|
||||
export declare function replace(str: string, oldvalue: string, newvalue: string, count?: number | null): string;
|
||||
//# sourceMappingURL=utils.d.ts.map
|
||||
1
node_modules/@huggingface/jinja/dist/utils.d.ts.map
generated
vendored
Normal file
1
node_modules/@huggingface/jinja/dist/utils.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,SAAI,GAAG,MAAM,EAAE,CAqBtE;AAED;;;;;;;GAOG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,SAAI,GAAG,CAAC,EAAE,CAgBjF;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CA6B3D;AAMD;;GAEG;AACH,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAYtG"}
|
||||
54
node_modules/@huggingface/jinja/package.json
generated
vendored
Normal file
54
node_modules/@huggingface/jinja/package.json
generated
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"name": "@huggingface/jinja",
|
||||
"version": "0.5.5",
|
||||
"description": "A minimalistic JavaScript implementation of the Jinja templating engine, specifically designed for parsing and rendering ML chat templates.",
|
||||
"keywords": [
|
||||
"face",
|
||||
"hugging",
|
||||
"huggingface",
|
||||
"jinja",
|
||||
"templates"
|
||||
],
|
||||
"license": "MIT",
|
||||
"author": "Hugging Face",
|
||||
"repository": "https://github.com/huggingface/huggingface.js.git",
|
||||
"source": "src/index.ts",
|
||||
"files": [
|
||||
"dist",
|
||||
"README.md",
|
||||
"src",
|
||||
"tsconfig.json"
|
||||
],
|
||||
"type": "module",
|
||||
"main": "./dist/index.cjs",
|
||||
"module": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"require": "./dist/index.cjs",
|
||||
"import": "./dist/index.js"
|
||||
}
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@huggingface/transformers": "^3.0.0",
|
||||
"typescript": "^5.3.2",
|
||||
"@huggingface/hub": "^2.8.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "eslint --quiet --fix --ext .cjs,.ts .",
|
||||
"lint:check": "eslint --ext .cjs,.ts .",
|
||||
"format": "oxfmt .",
|
||||
"format:check": "oxfmt --check .",
|
||||
"build": "tsup src/index.ts --format cjs,esm --clean && tsc --emitDeclarationOnly --declaration",
|
||||
"test": "vitest run",
|
||||
"test:browser": "vitest run --browser.name=chrome --browser.headless",
|
||||
"check": "tsc"
|
||||
}
|
||||
}
|
||||
320
node_modules/@huggingface/jinja/src/ast.ts
generated
vendored
Normal file
320
node_modules/@huggingface/jinja/src/ast.ts
generated
vendored
Normal file
@@ -0,0 +1,320 @@
|
||||
import type { Token } from "./lexer";
|
||||
|
||||
/**
|
||||
* Statements do not result in a value at runtime. They contain one or more expressions internally.
|
||||
*/
|
||||
export class Statement {
|
||||
type = "Statement";
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines a block which contains many statements. Each chat template corresponds to one Program.
|
||||
*/
|
||||
export class Program extends Statement {
|
||||
override type = "Program";
|
||||
|
||||
constructor(public body: Statement[]) {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
export class If extends Statement {
|
||||
override type = "If";
|
||||
|
||||
constructor(
|
||||
public test: Expression,
|
||||
public body: Statement[],
|
||||
public alternate: Statement[],
|
||||
) {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loop over each item in a sequence
|
||||
* https://jinja.palletsprojects.com/en/3.0.x/templates/#for
|
||||
*/
|
||||
export class For extends Statement {
|
||||
override type = "For";
|
||||
|
||||
constructor(
|
||||
public loopvar: Identifier | TupleLiteral,
|
||||
public iterable: Expression,
|
||||
public body: Statement[],
|
||||
public defaultBlock: Statement[], // if no iteration took place
|
||||
) {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
export class Break extends Statement {
|
||||
override type = "Break";
|
||||
}
|
||||
export class Continue extends Statement {
|
||||
override type = "Continue";
|
||||
}
|
||||
|
||||
export class SetStatement extends Statement {
|
||||
override type = "Set";
|
||||
constructor(
|
||||
public assignee: Expression,
|
||||
public value: Expression | null,
|
||||
public body: Statement[],
|
||||
) {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
export class Macro extends Statement {
|
||||
override type = "Macro";
|
||||
|
||||
constructor(
|
||||
public name: Identifier,
|
||||
public args: Expression[],
|
||||
public body: Statement[],
|
||||
) {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
export class Comment extends Statement {
|
||||
override type = "Comment";
|
||||
constructor(public value: string) {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Expressions will result in a value at runtime (unlike statements).
|
||||
*/
|
||||
export class Expression extends Statement {
|
||||
override type = "Expression";
|
||||
}
|
||||
|
||||
export class MemberExpression extends Expression {
|
||||
override type = "MemberExpression";
|
||||
|
||||
constructor(
|
||||
public object: Expression,
|
||||
public property: Expression,
|
||||
public computed: boolean,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
export class CallExpression extends Expression {
|
||||
override type = "CallExpression";
|
||||
|
||||
constructor(
|
||||
public callee: Expression,
|
||||
public args: Expression[],
|
||||
) {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a user-defined variable or symbol in the template.
|
||||
*/
|
||||
export class Identifier extends Expression {
|
||||
override type = "Identifier";
|
||||
|
||||
/**
|
||||
* @param {string} value The name of the identifier
|
||||
*/
|
||||
constructor(public value: string) {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract base class for all Literal expressions.
|
||||
* Should not be instantiated directly.
|
||||
*/
|
||||
abstract class Literal<T> extends Expression {
|
||||
override type = "Literal";
|
||||
|
||||
constructor(public value: T) {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
export class IntegerLiteral extends Literal<number> {
|
||||
override type = "IntegerLiteral";
|
||||
}
|
||||
|
||||
export class FloatLiteral extends Literal<number> {
|
||||
override type = "FloatLiteral";
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a text constant in the template.
|
||||
*/
|
||||
export class StringLiteral extends Literal<string> {
|
||||
override type = "StringLiteral";
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents an array literal in the template.
|
||||
*/
|
||||
export class ArrayLiteral extends Literal<Expression[]> {
|
||||
override type = "ArrayLiteral";
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a tuple literal in the template.
|
||||
*/
|
||||
export class TupleLiteral extends Literal<Expression[]> {
|
||||
override type = "TupleLiteral";
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents an object literal in the template.
|
||||
*/
|
||||
export class ObjectLiteral extends Literal<Map<Expression, Expression>> {
|
||||
override type = "ObjectLiteral";
|
||||
}
|
||||
|
||||
/**
|
||||
* An operation with two sides, separated by an operator.
|
||||
* Note: Either side can be a Complex Expression, with order
|
||||
* of operations being determined by the operator.
|
||||
*/
|
||||
export class BinaryExpression extends Expression {
|
||||
override type = "BinaryExpression";
|
||||
|
||||
constructor(
|
||||
public operator: Token,
|
||||
public left: Expression,
|
||||
public right: Expression,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An operation with two sides, separated by the | operator.
|
||||
* Operator precedence: https://github.com/pallets/jinja/issues/379#issuecomment-168076202
|
||||
*/
|
||||
export class FilterExpression extends Expression {
|
||||
override type = "FilterExpression";
|
||||
|
||||
constructor(
|
||||
public operand: Expression,
|
||||
public filter: Identifier | CallExpression,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
export class FilterStatement extends Statement {
|
||||
override type = "FilterStatement";
|
||||
|
||||
constructor(
|
||||
public filter: Identifier | CallExpression,
|
||||
public body: Statement[],
|
||||
) {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An operation which filters a sequence of objects by applying a test to each object,
|
||||
* and only selecting the objects with the test succeeding.
|
||||
*
|
||||
* It may also be used as a shortcut for a ternary operator.
|
||||
*/
|
||||
export class SelectExpression extends Expression {
|
||||
override type = "SelectExpression";
|
||||
|
||||
constructor(
|
||||
public lhs: Expression,
|
||||
public test: Expression,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An operation with two sides, separated by the "is" operator.
|
||||
*/
|
||||
export class TestExpression extends Expression {
|
||||
override type = "TestExpression";
|
||||
|
||||
constructor(
|
||||
public operand: Expression,
|
||||
public negate: boolean,
|
||||
public test: Identifier, // TODO: Add support for non-identifier tests
|
||||
) {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An operation with one side (operator on the left).
|
||||
*/
|
||||
export class UnaryExpression extends Expression {
|
||||
override type = "UnaryExpression";
|
||||
|
||||
constructor(
|
||||
public operator: Token,
|
||||
public argument: Expression,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
export class SliceExpression extends Expression {
|
||||
override type = "SliceExpression";
|
||||
|
||||
constructor(
|
||||
public start: Expression | undefined = undefined,
|
||||
public stop: Expression | undefined = undefined,
|
||||
public step: Expression | undefined = undefined,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
export class KeywordArgumentExpression extends Expression {
|
||||
override type = "KeywordArgumentExpression";
|
||||
|
||||
constructor(
|
||||
public key: Identifier,
|
||||
public value: Expression,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
export class SpreadExpression extends Expression {
|
||||
override type = "SpreadExpression";
|
||||
|
||||
constructor(public argument: Expression) {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
export class CallStatement extends Statement {
|
||||
override type = "CallStatement";
|
||||
|
||||
constructor(
|
||||
public call: CallExpression,
|
||||
public callerArgs: Expression[] | null,
|
||||
public body: Statement[],
|
||||
) {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
export class Ternary extends Expression {
|
||||
override type = "Ternary";
|
||||
constructor(
|
||||
public condition: Expression,
|
||||
public trueExpr: Expression,
|
||||
public falseExpr: Expression,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
}
|
||||
318
node_modules/@huggingface/jinja/src/format.ts
generated
vendored
Normal file
318
node_modules/@huggingface/jinja/src/format.ts
generated
vendored
Normal file
@@ -0,0 +1,318 @@
|
||||
import type {
|
||||
Program,
|
||||
Statement,
|
||||
Comment,
|
||||
If,
|
||||
For,
|
||||
SetStatement,
|
||||
Macro,
|
||||
Expression,
|
||||
MemberExpression,
|
||||
CallExpression,
|
||||
Identifier,
|
||||
FloatLiteral,
|
||||
IntegerLiteral,
|
||||
StringLiteral,
|
||||
ArrayLiteral,
|
||||
TupleLiteral,
|
||||
ObjectLiteral,
|
||||
BinaryExpression,
|
||||
FilterExpression,
|
||||
SelectExpression,
|
||||
TestExpression,
|
||||
UnaryExpression,
|
||||
SliceExpression,
|
||||
KeywordArgumentExpression,
|
||||
CallStatement,
|
||||
FilterStatement,
|
||||
SpreadExpression,
|
||||
Ternary,
|
||||
} from "./ast";
|
||||
|
||||
const NEWLINE = "\n";
|
||||
const OPEN_STATEMENT = "{%- ";
|
||||
const CLOSE_STATEMENT = " -%}";
|
||||
|
||||
function getBinaryOperatorPrecedence(expr: BinaryExpression): number {
|
||||
switch (expr.operator.type) {
|
||||
case "MultiplicativeBinaryOperator":
|
||||
return 4;
|
||||
case "AdditiveBinaryOperator":
|
||||
return 3;
|
||||
case "ComparisonBinaryOperator":
|
||||
return 2;
|
||||
case "Identifier":
|
||||
if (expr.operator.value === "and") return 1;
|
||||
if (expr.operator.value === "in" || expr.operator.value === "not in") return 2;
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
export function format(program: Program, indent: string | number = "\t"): string {
|
||||
const indentStr = typeof indent === "number" ? " ".repeat(indent) : indent;
|
||||
const body = formatStatements(program.body, 0, indentStr);
|
||||
return body.replace(/\n$/, "");
|
||||
}
|
||||
|
||||
function createStatement(...text: string[]): string {
|
||||
return OPEN_STATEMENT + text.join(" ") + CLOSE_STATEMENT;
|
||||
}
|
||||
|
||||
function formatStatements(stmts: Statement[], depth: number, indentStr: string): string {
|
||||
return stmts.map((stmt) => formatStatement(stmt, depth, indentStr)).join(NEWLINE);
|
||||
}
|
||||
|
||||
function formatStatement(node: Statement, depth: number, indentStr: string): string {
|
||||
const pad = indentStr.repeat(depth);
|
||||
switch (node.type) {
|
||||
case "Program":
|
||||
return formatStatements((node as Program).body, depth, indentStr);
|
||||
case "If":
|
||||
return formatIf(node as If, depth, indentStr);
|
||||
case "For":
|
||||
return formatFor(node as For, depth, indentStr);
|
||||
case "Set":
|
||||
return formatSet(node as SetStatement, depth, indentStr);
|
||||
case "Macro":
|
||||
return formatMacro(node as Macro, depth, indentStr);
|
||||
case "Break":
|
||||
return pad + createStatement("break");
|
||||
case "Continue":
|
||||
return pad + createStatement("continue");
|
||||
case "CallStatement":
|
||||
return formatCallStatement(node as CallStatement, depth, indentStr);
|
||||
case "FilterStatement":
|
||||
return formatFilterStatement(node as FilterStatement, depth, indentStr);
|
||||
case "Comment":
|
||||
return pad + "{# " + (node as Comment).value + " #}";
|
||||
default:
|
||||
return pad + "{{- " + formatExpression(node as Expression) + " -}}";
|
||||
}
|
||||
}
|
||||
|
||||
function formatIf(node: If, depth: number, indentStr: string): string {
|
||||
const pad = indentStr.repeat(depth);
|
||||
|
||||
const clauses: { test: Expression; body: Statement[] }[] = [];
|
||||
let current: If | undefined = node;
|
||||
while (current) {
|
||||
clauses.push({ test: current.test, body: current.body });
|
||||
if (current.alternate.length === 1 && current.alternate[0].type === "If") {
|
||||
current = current.alternate[0] as If;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// IF
|
||||
let out =
|
||||
pad +
|
||||
createStatement("if", formatExpression(clauses[0].test)) +
|
||||
NEWLINE +
|
||||
formatStatements(clauses[0].body, depth + 1, indentStr);
|
||||
|
||||
// ELIF(s)
|
||||
for (let i = 1; i < clauses.length; ++i) {
|
||||
out +=
|
||||
NEWLINE +
|
||||
pad +
|
||||
createStatement("elif", formatExpression(clauses[i].test)) +
|
||||
NEWLINE +
|
||||
formatStatements(clauses[i].body, depth + 1, indentStr);
|
||||
}
|
||||
|
||||
// ELSE
|
||||
if (current && current.alternate.length > 0) {
|
||||
out +=
|
||||
NEWLINE + pad + createStatement("else") + NEWLINE + formatStatements(current.alternate, depth + 1, indentStr);
|
||||
}
|
||||
|
||||
// ENDIF
|
||||
out += NEWLINE + pad + createStatement("endif");
|
||||
return out;
|
||||
}
|
||||
|
||||
function formatFor(node: For, depth: number, indentStr: string): string {
|
||||
const pad = indentStr.repeat(depth);
|
||||
let formattedIterable = "";
|
||||
if (node.iterable.type === "SelectExpression") {
|
||||
// Handle special case: e.g., `for x in [1, 2, 3] if x > 2`
|
||||
const n = node.iterable as SelectExpression;
|
||||
formattedIterable = `${formatExpression(n.lhs)} if ${formatExpression(n.test)}`;
|
||||
} else {
|
||||
formattedIterable = formatExpression(node.iterable);
|
||||
}
|
||||
let out =
|
||||
pad +
|
||||
createStatement("for", formatExpression(node.loopvar), "in", formattedIterable) +
|
||||
NEWLINE +
|
||||
formatStatements(node.body, depth + 1, indentStr);
|
||||
|
||||
if (node.defaultBlock.length > 0) {
|
||||
out +=
|
||||
NEWLINE + pad + createStatement("else") + NEWLINE + formatStatements(node.defaultBlock, depth + 1, indentStr);
|
||||
}
|
||||
|
||||
out += NEWLINE + pad + createStatement("endfor");
|
||||
return out;
|
||||
}
|
||||
|
||||
function formatSet(node: SetStatement, depth: number, indentStr: string): string {
|
||||
const pad = indentStr.repeat(depth);
|
||||
const left = formatExpression(node.assignee);
|
||||
const right = node.value ? formatExpression(node.value) : "";
|
||||
|
||||
const value = pad + createStatement("set", `${left}${node.value ? " = " + right : ""}`);
|
||||
if (node.body.length === 0) {
|
||||
return value;
|
||||
}
|
||||
return (
|
||||
value + NEWLINE + formatStatements(node.body, depth + 1, indentStr) + NEWLINE + pad + createStatement("endset")
|
||||
);
|
||||
}
|
||||
|
||||
function formatMacro(node: Macro, depth: number, indentStr: string): string {
|
||||
const pad = indentStr.repeat(depth);
|
||||
const args = node.args.map(formatExpression).join(", ");
|
||||
return (
|
||||
pad +
|
||||
createStatement("macro", `${node.name.value}(${args})`) +
|
||||
NEWLINE +
|
||||
formatStatements(node.body, depth + 1, indentStr) +
|
||||
NEWLINE +
|
||||
pad +
|
||||
createStatement("endmacro")
|
||||
);
|
||||
}
|
||||
|
||||
function formatCallStatement(node: CallStatement, depth: number, indentStr: string): string {
|
||||
const pad = indentStr.repeat(depth);
|
||||
const params =
|
||||
node.callerArgs && node.callerArgs.length > 0 ? `(${node.callerArgs.map(formatExpression).join(", ")})` : "";
|
||||
const callExpr = formatExpression(node.call);
|
||||
let out = pad + createStatement(`call${params}`, callExpr) + NEWLINE;
|
||||
out += formatStatements(node.body, depth + 1, indentStr) + NEWLINE;
|
||||
out += pad + createStatement("endcall");
|
||||
return out;
|
||||
}
|
||||
|
||||
function formatFilterStatement(node: FilterStatement, depth: number, indentStr: string): string {
|
||||
const pad = indentStr.repeat(depth);
|
||||
const spec =
|
||||
node.filter.type === "Identifier"
|
||||
? (node.filter as Identifier).value
|
||||
: formatExpression(node.filter as CallExpression);
|
||||
let out = pad + createStatement("filter", spec) + NEWLINE;
|
||||
out += formatStatements(node.body, depth + 1, indentStr) + NEWLINE;
|
||||
out += pad + createStatement("endfilter");
|
||||
return out;
|
||||
}
|
||||
|
||||
function formatExpression(node: Expression, parentPrec: number = -1): string {
|
||||
switch (node.type) {
|
||||
case "SpreadExpression": {
|
||||
const n = node as SpreadExpression;
|
||||
return `*${formatExpression(n.argument)}`;
|
||||
}
|
||||
case "Identifier":
|
||||
return (node as Identifier).value;
|
||||
case "IntegerLiteral":
|
||||
return `${(node as IntegerLiteral).value}`;
|
||||
case "FloatLiteral":
|
||||
return `${(node as FloatLiteral).value}`;
|
||||
case "StringLiteral":
|
||||
return JSON.stringify((node as StringLiteral).value);
|
||||
case "BinaryExpression": {
|
||||
const n = node as BinaryExpression;
|
||||
const thisPrecedence = getBinaryOperatorPrecedence(n);
|
||||
const left = formatExpression(n.left, thisPrecedence);
|
||||
const right = formatExpression(n.right, thisPrecedence + 1);
|
||||
const expr = `${left} ${n.operator.value} ${right}`;
|
||||
return thisPrecedence < parentPrec ? `(${expr})` : expr;
|
||||
}
|
||||
case "UnaryExpression": {
|
||||
const n = node as UnaryExpression;
|
||||
const val = n.operator.value + (n.operator.value === "not" ? " " : "") + formatExpression(n.argument, Infinity);
|
||||
return val;
|
||||
}
|
||||
case "CallExpression": {
|
||||
const n = node as CallExpression;
|
||||
const args = n.args.map(formatExpression).join(", ");
|
||||
return `${formatExpression(n.callee)}(${args})`;
|
||||
}
|
||||
case "MemberExpression": {
|
||||
const n = node as MemberExpression;
|
||||
let obj = formatExpression(n.object);
|
||||
// only wrap if it's not a simple or chained access/call
|
||||
if (
|
||||
![
|
||||
"Identifier",
|
||||
"MemberExpression",
|
||||
"CallExpression",
|
||||
"StringLiteral",
|
||||
"IntegerLiteral",
|
||||
"FloatLiteral",
|
||||
"ArrayLiteral",
|
||||
"TupleLiteral",
|
||||
"ObjectLiteral",
|
||||
].includes(n.object.type)
|
||||
) {
|
||||
obj = `(${obj})`;
|
||||
}
|
||||
let prop = formatExpression(n.property);
|
||||
if (!n.computed && n.property.type !== "Identifier") {
|
||||
prop = `(${prop})`;
|
||||
}
|
||||
return n.computed ? `${obj}[${prop}]` : `${obj}.${prop}`;
|
||||
}
|
||||
case "FilterExpression": {
|
||||
const n = node as FilterExpression;
|
||||
const operand = formatExpression(n.operand, Infinity);
|
||||
if (n.filter.type === "CallExpression") {
|
||||
return `${operand} | ${formatExpression(n.filter)}`;
|
||||
}
|
||||
return `${operand} | ${(n.filter as Identifier).value}`;
|
||||
}
|
||||
case "SelectExpression": {
|
||||
const n = node as SelectExpression;
|
||||
return `${formatExpression(n.lhs)} if ${formatExpression(n.test)}`;
|
||||
}
|
||||
case "TestExpression": {
|
||||
const n = node as TestExpression;
|
||||
return `${formatExpression(n.operand)} is${n.negate ? " not" : ""} ${n.test.value}`;
|
||||
}
|
||||
case "ArrayLiteral":
|
||||
case "TupleLiteral": {
|
||||
const elems = ((node as ArrayLiteral | TupleLiteral).value as Expression[]).map(formatExpression);
|
||||
const brackets = node.type === "ArrayLiteral" ? "[]" : "()";
|
||||
return `${brackets[0]}${elems.join(", ")}${brackets[1]}`;
|
||||
}
|
||||
case "ObjectLiteral": {
|
||||
const entries = Array.from((node as ObjectLiteral).value.entries()).map(
|
||||
([k, v]) => `${formatExpression(k)}: ${formatExpression(v)}`,
|
||||
);
|
||||
return `{${entries.join(", ")}}`;
|
||||
}
|
||||
case "SliceExpression": {
|
||||
const n = node as SliceExpression;
|
||||
const s = n.start ? formatExpression(n.start) : "";
|
||||
const t = n.stop ? formatExpression(n.stop) : "";
|
||||
const st = n.step ? `:${formatExpression(n.step)}` : "";
|
||||
return `${s}:${t}${st}`;
|
||||
}
|
||||
case "KeywordArgumentExpression": {
|
||||
const n = node as KeywordArgumentExpression;
|
||||
return `${n.key.value}=${formatExpression(n.value)}`;
|
||||
}
|
||||
case "Ternary": {
|
||||
const n = node as Ternary;
|
||||
const expr = `${formatExpression(n.trueExpr)} if ${formatExpression(n.condition, 0)} else ${formatExpression(
|
||||
n.falseExpr,
|
||||
)}`;
|
||||
return parentPrec > -1 ? `(${expr})` : expr;
|
||||
}
|
||||
default:
|
||||
throw new Error(`Unknown expression type: ${node.type}`);
|
||||
}
|
||||
}
|
||||
57
node_modules/@huggingface/jinja/src/index.ts
generated
vendored
Normal file
57
node_modules/@huggingface/jinja/src/index.ts
generated
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* @file Jinja templating engine
|
||||
*
|
||||
* A minimalistic JavaScript reimplementation of the [Jinja](https://github.com/pallets/jinja) templating engine,
|
||||
* to support the chat templates. Special thanks to [Tyler Laceby](https://github.com/tlaceby) for his amazing
|
||||
* ["Guide to Interpreters"](https://github.com/tlaceby/guide-to-interpreters-series) tutorial series,
|
||||
* which provided the basis for this implementation.
|
||||
*
|
||||
* See the [Transformers documentation](https://huggingface.co/docs/transformers/main/en/chat_templating) for more information.
|
||||
*
|
||||
* @module index
|
||||
*/
|
||||
import { tokenize } from "./lexer";
|
||||
import { parse } from "./parser";
|
||||
import { Environment, Interpreter, setupGlobals } from "./runtime";
|
||||
import type { Program } from "./ast";
|
||||
import type { StringValue } from "./runtime";
|
||||
import { format } from "./format";
|
||||
|
||||
export class Template {
|
||||
parsed: Program;
|
||||
|
||||
/**
|
||||
* @param {string} template The template string
|
||||
*/
|
||||
constructor(template: string) {
|
||||
const tokens = tokenize(template, {
|
||||
lstrip_blocks: true,
|
||||
trim_blocks: true,
|
||||
});
|
||||
this.parsed = parse(tokens);
|
||||
}
|
||||
|
||||
render(items?: Record<string, unknown>): string {
|
||||
// Create a new environment for this template
|
||||
const env = new Environment();
|
||||
setupGlobals(env);
|
||||
|
||||
// Add user-defined variables
|
||||
if (items) {
|
||||
for (const [key, value] of Object.entries(items)) {
|
||||
env.set(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
const interpreter = new Interpreter(env);
|
||||
|
||||
const result = interpreter.run(this.parsed) as StringValue;
|
||||
return result.value;
|
||||
}
|
||||
|
||||
format(options?: { indent: string | number }): string {
|
||||
return format(this.parsed, options?.indent || "\t");
|
||||
}
|
||||
}
|
||||
|
||||
export { Environment, Interpreter, tokenize, parse };
|
||||
394
node_modules/@huggingface/jinja/src/lexer.ts
generated
vendored
Normal file
394
node_modules/@huggingface/jinja/src/lexer.ts
generated
vendored
Normal file
@@ -0,0 +1,394 @@
|
||||
/**
|
||||
* Represents tokens that our language understands in parsing.
|
||||
*/
|
||||
export const TOKEN_TYPES = Object.freeze({
|
||||
Text: "Text", // The text between Jinja statements or expressions
|
||||
|
||||
NumericLiteral: "NumericLiteral", // e.g., 123, 1.0
|
||||
StringLiteral: "StringLiteral", // 'string'
|
||||
Identifier: "Identifier", // Variables, functions, statements, booleans, etc.
|
||||
Equals: "Equals", // =
|
||||
OpenParen: "OpenParen", // (
|
||||
CloseParen: "CloseParen", // )
|
||||
OpenStatement: "OpenStatement", // {%
|
||||
CloseStatement: "CloseStatement", // %}
|
||||
OpenExpression: "OpenExpression", // {{
|
||||
CloseExpression: "CloseExpression", // }}
|
||||
OpenSquareBracket: "OpenSquareBracket", // [
|
||||
CloseSquareBracket: "CloseSquareBracket", // ]
|
||||
OpenCurlyBracket: "OpenCurlyBracket", // {
|
||||
CloseCurlyBracket: "CloseCurlyBracket", // }
|
||||
Comma: "Comma", // ,
|
||||
Dot: "Dot", // .
|
||||
Colon: "Colon", // :
|
||||
Pipe: "Pipe", // |
|
||||
|
||||
CallOperator: "CallOperator", // ()
|
||||
AdditiveBinaryOperator: "AdditiveBinaryOperator", // + - ~
|
||||
MultiplicativeBinaryOperator: "MultiplicativeBinaryOperator", // * / %
|
||||
ComparisonBinaryOperator: "ComparisonBinaryOperator", // < > <= >= == !=
|
||||
UnaryOperator: "UnaryOperator", // ! - +
|
||||
Comment: "Comment", // {# ... #}
|
||||
});
|
||||
|
||||
export type TokenType = keyof typeof TOKEN_TYPES;
|
||||
|
||||
/**
|
||||
* Represents a single token in the template.
|
||||
*/
|
||||
export class Token {
|
||||
/**
|
||||
* Constructs a new Token.
|
||||
* @param {string} value The raw value as seen inside the source code.
|
||||
* @param {TokenType} type The type of token.
|
||||
*/
|
||||
constructor(
|
||||
public value: string,
|
||||
public type: TokenType,
|
||||
) {}
|
||||
}
|
||||
|
||||
function isWord(char: string): boolean {
|
||||
return /\w/.test(char);
|
||||
}
|
||||
|
||||
function isInteger(char: string): boolean {
|
||||
return /[0-9]/.test(char);
|
||||
}
|
||||
|
||||
function isWhitespace(char: string): boolean {
|
||||
return /\s/.test(char);
|
||||
}
|
||||
|
||||
/**
|
||||
* A data structure which contains a list of rules to test
|
||||
*/
|
||||
const ORDERED_MAPPING_TABLE: [string, TokenType][] = [
|
||||
// Control sequences
|
||||
["{%", TOKEN_TYPES.OpenStatement],
|
||||
["%}", TOKEN_TYPES.CloseStatement],
|
||||
["{{", TOKEN_TYPES.OpenExpression],
|
||||
["}}", TOKEN_TYPES.CloseExpression],
|
||||
// Single character tokens
|
||||
["(", TOKEN_TYPES.OpenParen],
|
||||
[")", TOKEN_TYPES.CloseParen],
|
||||
["{", TOKEN_TYPES.OpenCurlyBracket],
|
||||
["}", TOKEN_TYPES.CloseCurlyBracket],
|
||||
["[", TOKEN_TYPES.OpenSquareBracket],
|
||||
["]", TOKEN_TYPES.CloseSquareBracket],
|
||||
[",", TOKEN_TYPES.Comma],
|
||||
[".", TOKEN_TYPES.Dot],
|
||||
[":", TOKEN_TYPES.Colon],
|
||||
["|", TOKEN_TYPES.Pipe],
|
||||
// Comparison operators
|
||||
["<=", TOKEN_TYPES.ComparisonBinaryOperator],
|
||||
[">=", TOKEN_TYPES.ComparisonBinaryOperator],
|
||||
["==", TOKEN_TYPES.ComparisonBinaryOperator],
|
||||
["!=", TOKEN_TYPES.ComparisonBinaryOperator],
|
||||
["<", TOKEN_TYPES.ComparisonBinaryOperator],
|
||||
[">", TOKEN_TYPES.ComparisonBinaryOperator],
|
||||
// Arithmetic operators
|
||||
["+", TOKEN_TYPES.AdditiveBinaryOperator],
|
||||
["-", TOKEN_TYPES.AdditiveBinaryOperator],
|
||||
["~", TOKEN_TYPES.AdditiveBinaryOperator],
|
||||
["*", TOKEN_TYPES.MultiplicativeBinaryOperator],
|
||||
["/", TOKEN_TYPES.MultiplicativeBinaryOperator],
|
||||
["%", TOKEN_TYPES.MultiplicativeBinaryOperator],
|
||||
// Assignment operator
|
||||
["=", TOKEN_TYPES.Equals],
|
||||
];
|
||||
|
||||
const ESCAPE_CHARACTERS = new Map([
|
||||
["n", "\n"], // New line
|
||||
["t", "\t"], // Horizontal tab
|
||||
["r", "\r"], // Carriage return
|
||||
["b", "\b"], // Backspace
|
||||
["f", "\f"], // Form feed
|
||||
["v", "\v"], // Vertical tab
|
||||
["'", "'"], // Single quote
|
||||
['"', '"'], // Double quote
|
||||
["\\", "\\"], // Backslash
|
||||
]);
|
||||
|
||||
export interface PreprocessOptions {
|
||||
trim_blocks?: boolean;
|
||||
lstrip_blocks?: boolean;
|
||||
}
|
||||
|
||||
function preprocess(template: string, options: PreprocessOptions = {}): string {
|
||||
// According to https://jinja.palletsprojects.com/en/3.0.x/templates/#whitespace-control
|
||||
|
||||
// In the default configuration:
|
||||
// - a single trailing newline is stripped if present
|
||||
// - other whitespace (spaces, tabs, newlines etc.) is returned unchanged
|
||||
if (template.endsWith("\n")) {
|
||||
template = template.slice(0, -1);
|
||||
}
|
||||
|
||||
if (options.lstrip_blocks) {
|
||||
// The lstrip_blocks option can also be set to strip tabs and spaces from the
|
||||
// beginning of a line to the start of a block. (Nothing will be stripped if
|
||||
// there are other characters before the start of the block.)
|
||||
template = template.replace(/^[ \t]*({[#%-])/gm, "$1");
|
||||
}
|
||||
|
||||
if (options.trim_blocks) {
|
||||
// If an application configures Jinja to trim_blocks, the first newline after
|
||||
// a template tag is removed automatically (like in PHP).
|
||||
template = template.replace(/([#%-]})\n/g, "$1");
|
||||
}
|
||||
|
||||
// Handle the custom transformers-specific `generation` tag.
|
||||
// See https://github.com/huggingface/transformers/pull/30650 for more information.
|
||||
return template.replace(/{%\s*(end)?generation\s*%}/gs, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a list of tokens from a source string.
|
||||
*/
|
||||
export function tokenize(source: string, options: PreprocessOptions = {}): Token[] {
|
||||
const tokens: Token[] = [];
|
||||
const src: string = preprocess(source, options);
|
||||
|
||||
let cursorPosition = 0;
|
||||
let curlyBracketDepth = 0;
|
||||
|
||||
const consumeWhile = (predicate: (char: string) => boolean): string => {
|
||||
let str = "";
|
||||
while (predicate(src[cursorPosition])) {
|
||||
// Check for escaped characters
|
||||
if (src[cursorPosition] === "\\") {
|
||||
// Consume the backslash
|
||||
++cursorPosition;
|
||||
// Check for end of input
|
||||
if (cursorPosition >= src.length) throw new SyntaxError("Unexpected end of input");
|
||||
|
||||
// Add the escaped character
|
||||
const escaped = src[cursorPosition++];
|
||||
const unescaped = ESCAPE_CHARACTERS.get(escaped);
|
||||
if (unescaped === undefined) {
|
||||
throw new SyntaxError(`Unexpected escaped character: ${escaped}`);
|
||||
}
|
||||
str += unescaped;
|
||||
continue;
|
||||
}
|
||||
|
||||
str += src[cursorPosition++];
|
||||
if (cursorPosition >= src.length) throw new SyntaxError("Unexpected end of input");
|
||||
}
|
||||
return str;
|
||||
};
|
||||
|
||||
const stripTrailingWhitespace = () => {
|
||||
const lastToken = tokens.at(-1);
|
||||
if (lastToken && lastToken.type === TOKEN_TYPES.Text) {
|
||||
lastToken.value = lastToken.value.trimEnd();
|
||||
if (lastToken.value === "") {
|
||||
tokens.pop(); // Remove empty text token
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const skipLeadingWhitespace = () => {
|
||||
while (cursorPosition < src.length && isWhitespace(src[cursorPosition])) {
|
||||
++cursorPosition;
|
||||
}
|
||||
};
|
||||
|
||||
// Build each token until end of input
|
||||
main: while (cursorPosition < src.length) {
|
||||
// First, consume all text that is outside of a Jinja statement or expression
|
||||
const lastTokenType = tokens.at(-1)?.type;
|
||||
if (
|
||||
lastTokenType === undefined ||
|
||||
lastTokenType === TOKEN_TYPES.CloseStatement ||
|
||||
lastTokenType === TOKEN_TYPES.CloseExpression ||
|
||||
lastTokenType === TOKEN_TYPES.Comment
|
||||
) {
|
||||
let text = "";
|
||||
while (
|
||||
cursorPosition < src.length &&
|
||||
// Keep going until we hit the next Jinja statement or expression
|
||||
!(
|
||||
src[cursorPosition] === "{" &&
|
||||
(src[cursorPosition + 1] === "%" || src[cursorPosition + 1] === "{" || src[cursorPosition + 1] === "#")
|
||||
)
|
||||
) {
|
||||
// Consume text
|
||||
text += src[cursorPosition++];
|
||||
}
|
||||
|
||||
// There is some text to add
|
||||
if (text.length > 0) {
|
||||
tokens.push(new Token(text, TOKEN_TYPES.Text));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Possibly consume a comment
|
||||
if (src[cursorPosition] === "{" && src[cursorPosition + 1] === "#") {
|
||||
cursorPosition += 2; // Skip the opening {#
|
||||
|
||||
// Check for leading hyphen for whitespace control {#-
|
||||
const stripBefore = src[cursorPosition] === "-";
|
||||
if (stripBefore) {
|
||||
++cursorPosition; // Skip the hyphen
|
||||
}
|
||||
|
||||
let comment = "";
|
||||
while (src[cursorPosition] !== "#" || src[cursorPosition + 1] !== "}") {
|
||||
// Check for end of input
|
||||
if (cursorPosition + 2 >= src.length) {
|
||||
throw new SyntaxError("Missing end of comment tag");
|
||||
}
|
||||
comment += src[cursorPosition++];
|
||||
}
|
||||
|
||||
// Check for trailing hyphen for whitespace control -#}
|
||||
const stripAfter = comment.endsWith("-");
|
||||
if (stripAfter) {
|
||||
comment = comment.slice(0, -1); // Remove the trailing hyphen
|
||||
}
|
||||
|
||||
// Apply whitespace stripping for leading hyphen
|
||||
if (stripBefore) {
|
||||
stripTrailingWhitespace();
|
||||
}
|
||||
|
||||
tokens.push(new Token(comment, TOKEN_TYPES.Comment));
|
||||
cursorPosition += 2; // Skip the closing #}
|
||||
|
||||
// Apply whitespace stripping for trailing hyphen
|
||||
if (stripAfter) {
|
||||
skipLeadingWhitespace();
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check for opening statement with whitespace control {%-
|
||||
if (src.slice(cursorPosition, cursorPosition + 3) === "{%-") {
|
||||
stripTrailingWhitespace();
|
||||
tokens.push(new Token("{%", TOKEN_TYPES.OpenStatement));
|
||||
cursorPosition += 3; // Skip {%-
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check for opening expression with whitespace control {{-
|
||||
if (src.slice(cursorPosition, cursorPosition + 3) === "{{-") {
|
||||
stripTrailingWhitespace();
|
||||
tokens.push(new Token("{{", TOKEN_TYPES.OpenExpression));
|
||||
curlyBracketDepth = 0;
|
||||
cursorPosition += 3; // Skip {{-
|
||||
continue;
|
||||
}
|
||||
|
||||
// Consume (and ignore) all whitespace inside Jinja statements or expressions
|
||||
consumeWhile(isWhitespace);
|
||||
|
||||
// Check for closing statement with whitespace control -%}
|
||||
if (src.slice(cursorPosition, cursorPosition + 3) === "-%}") {
|
||||
tokens.push(new Token("%}", TOKEN_TYPES.CloseStatement));
|
||||
cursorPosition += 3; // Skip -%}
|
||||
skipLeadingWhitespace();
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check for closing expression with whitespace control -}}
|
||||
if (src.slice(cursorPosition, cursorPosition + 3) === "-}}") {
|
||||
tokens.push(new Token("}}", TOKEN_TYPES.CloseExpression));
|
||||
cursorPosition += 3; // Skip -}}
|
||||
skipLeadingWhitespace();
|
||||
continue;
|
||||
}
|
||||
|
||||
// Handle multi-character tokens
|
||||
const char = src[cursorPosition];
|
||||
|
||||
// Check for unary operators
|
||||
if (char === "-" || char === "+") {
|
||||
const lastTokenType = tokens.at(-1)?.type;
|
||||
if (lastTokenType === TOKEN_TYPES.Text || lastTokenType === undefined) {
|
||||
throw new SyntaxError(`Unexpected character: ${char}`);
|
||||
}
|
||||
switch (lastTokenType) {
|
||||
case TOKEN_TYPES.Identifier:
|
||||
case TOKEN_TYPES.NumericLiteral:
|
||||
case TOKEN_TYPES.StringLiteral:
|
||||
case TOKEN_TYPES.CloseParen:
|
||||
case TOKEN_TYPES.CloseSquareBracket:
|
||||
// Part of a binary operator
|
||||
// a - 1, 1 - 1, true - 1, "apple" - 1, (1) - 1, a[1] - 1
|
||||
// Continue parsing normally
|
||||
break;
|
||||
|
||||
default: {
|
||||
// Is part of a unary operator
|
||||
// (-1), [-1], (1 + -1), not -1, -apple
|
||||
++cursorPosition; // consume the unary operator
|
||||
|
||||
// Check for numbers following the unary operator
|
||||
const num = consumeWhile(isInteger);
|
||||
tokens.push(
|
||||
new Token(`${char}${num}`, num.length > 0 ? TOKEN_TYPES.NumericLiteral : TOKEN_TYPES.UnaryOperator),
|
||||
);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Try to match one of the tokens in the mapping table
|
||||
for (const [seq, type] of ORDERED_MAPPING_TABLE) {
|
||||
// inside an object literal, don't treat "}}" as expression-end
|
||||
if (seq === "}}" && curlyBracketDepth > 0) {
|
||||
continue;
|
||||
}
|
||||
const slice = src.slice(cursorPosition, cursorPosition + seq.length);
|
||||
if (slice === seq) {
|
||||
tokens.push(new Token(seq, type));
|
||||
|
||||
// possibly adjust the curly bracket depth
|
||||
if (type === TOKEN_TYPES.OpenExpression) {
|
||||
curlyBracketDepth = 0;
|
||||
} else if (type === TOKEN_TYPES.OpenCurlyBracket) {
|
||||
++curlyBracketDepth;
|
||||
} else if (type === TOKEN_TYPES.CloseCurlyBracket) {
|
||||
--curlyBracketDepth;
|
||||
}
|
||||
cursorPosition += seq.length;
|
||||
continue main;
|
||||
}
|
||||
}
|
||||
|
||||
if (char === "'" || char === '"') {
|
||||
++cursorPosition; // Skip the opening quote
|
||||
const str = consumeWhile((c) => c !== char);
|
||||
tokens.push(new Token(str, TOKEN_TYPES.StringLiteral));
|
||||
++cursorPosition; // Skip the closing quote
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isInteger(char)) {
|
||||
// Consume integer part
|
||||
let num = consumeWhile(isInteger);
|
||||
// Possibly, consume fractional part
|
||||
if (src[cursorPosition] === "." && isInteger(src[cursorPosition + 1])) {
|
||||
++cursorPosition; // consume '.'
|
||||
const frac = consumeWhile(isInteger);
|
||||
num = `${num}.${frac}`;
|
||||
}
|
||||
tokens.push(new Token(num, TOKEN_TYPES.NumericLiteral));
|
||||
continue;
|
||||
}
|
||||
if (isWord(char)) {
|
||||
// consume any word characters and always classify as Identifier
|
||||
const word = consumeWhile(isWord);
|
||||
tokens.push(new Token(word, TOKEN_TYPES.Identifier));
|
||||
continue;
|
||||
}
|
||||
|
||||
throw new SyntaxError(`Unexpected character: ${char}`);
|
||||
}
|
||||
|
||||
return tokens;
|
||||
}
|
||||
670
node_modules/@huggingface/jinja/src/parser.ts
generated
vendored
Normal file
670
node_modules/@huggingface/jinja/src/parser.ts
generated
vendored
Normal file
@@ -0,0 +1,670 @@
|
||||
import { Token, TOKEN_TYPES } from "./lexer";
|
||||
import type { TokenType } from "./lexer";
|
||||
import type { Statement } from "./ast";
|
||||
import {
|
||||
Program,
|
||||
If,
|
||||
For,
|
||||
Break,
|
||||
Continue,
|
||||
SetStatement,
|
||||
MemberExpression,
|
||||
CallExpression,
|
||||
Identifier,
|
||||
StringLiteral,
|
||||
ArrayLiteral,
|
||||
ObjectLiteral,
|
||||
BinaryExpression,
|
||||
FilterExpression,
|
||||
TestExpression,
|
||||
UnaryExpression,
|
||||
SliceExpression,
|
||||
KeywordArgumentExpression,
|
||||
TupleLiteral,
|
||||
Macro,
|
||||
SelectExpression,
|
||||
CallStatement,
|
||||
FilterStatement,
|
||||
SpreadExpression,
|
||||
IntegerLiteral,
|
||||
FloatLiteral,
|
||||
Ternary,
|
||||
Comment,
|
||||
} from "./ast";
|
||||
|
||||
/**
|
||||
* Generate the Abstract Syntax Tree (AST) from a list of tokens.
|
||||
* Operator precedence can be found here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_precedence#table
|
||||
*/
|
||||
export function parse(tokens: Token[]): Program {
|
||||
const program = new Program([]);
|
||||
let current = 0;
|
||||
|
||||
/**
|
||||
* Consume the next token if it matches the expected type, otherwise throw an error.
|
||||
* @param type The expected token type
|
||||
* @param error The error message to throw if the token does not match the expected type
|
||||
* @returns The consumed token
|
||||
*/
|
||||
function expect(type: string, error: string): Token {
|
||||
const prev = tokens[current++];
|
||||
if (!prev || prev.type !== type) {
|
||||
throw new Error(`Parser Error: ${error}. ${prev.type} !== ${type}.`);
|
||||
}
|
||||
return prev;
|
||||
}
|
||||
|
||||
function expectIdentifier(name: string): void {
|
||||
if (!isIdentifier(name)) {
|
||||
throw new SyntaxError(`Expected ${name}`);
|
||||
}
|
||||
++current;
|
||||
}
|
||||
|
||||
function parseAny(): Statement {
|
||||
switch (tokens[current].type) {
|
||||
case TOKEN_TYPES.Comment:
|
||||
return new Comment(tokens[current++].value);
|
||||
case TOKEN_TYPES.Text:
|
||||
return parseText();
|
||||
case TOKEN_TYPES.OpenStatement:
|
||||
return parseJinjaStatement();
|
||||
case TOKEN_TYPES.OpenExpression:
|
||||
return parseJinjaExpression();
|
||||
default:
|
||||
throw new SyntaxError(`Unexpected token type: ${tokens[current].type}`);
|
||||
}
|
||||
}
|
||||
|
||||
function is(...types: TokenType[]): boolean {
|
||||
return current + types.length <= tokens.length && types.every((type, i) => type === tokens[current + i].type);
|
||||
}
|
||||
|
||||
function isStatement(...names: string[]): boolean {
|
||||
return (
|
||||
tokens[current]?.type === TOKEN_TYPES.OpenStatement &&
|
||||
tokens[current + 1]?.type === TOKEN_TYPES.Identifier &&
|
||||
names.includes(tokens[current + 1]?.value)
|
||||
);
|
||||
}
|
||||
|
||||
function isIdentifier(...names: string[]): boolean {
|
||||
return (
|
||||
current + names.length <= tokens.length &&
|
||||
names.every((name, i) => tokens[current + i].type === "Identifier" && name === tokens[current + i].value)
|
||||
);
|
||||
}
|
||||
|
||||
function parseText(): StringLiteral {
|
||||
return new StringLiteral(expect(TOKEN_TYPES.Text, "Expected text token").value);
|
||||
}
|
||||
|
||||
function parseJinjaStatement(): Statement {
|
||||
// Consume {% token
|
||||
expect(TOKEN_TYPES.OpenStatement, "Expected opening statement token");
|
||||
|
||||
// next token must be Identifier whose .value tells us which statement
|
||||
if (tokens[current].type !== TOKEN_TYPES.Identifier) {
|
||||
throw new SyntaxError(`Unknown statement, got ${tokens[current].type}`);
|
||||
}
|
||||
const name = tokens[current].value;
|
||||
let result: Statement;
|
||||
switch (name) {
|
||||
case "set":
|
||||
++current;
|
||||
result = parseSetStatement();
|
||||
break;
|
||||
case "if":
|
||||
++current;
|
||||
result = parseIfStatement();
|
||||
// expect {% endif %}
|
||||
expect(TOKEN_TYPES.OpenStatement, "Expected {% token");
|
||||
expectIdentifier("endif");
|
||||
expect(TOKEN_TYPES.CloseStatement, "Expected %} token");
|
||||
break;
|
||||
case "macro":
|
||||
++current;
|
||||
result = parseMacroStatement();
|
||||
// expect {% endmacro %}
|
||||
expect(TOKEN_TYPES.OpenStatement, "Expected {% token");
|
||||
expectIdentifier("endmacro");
|
||||
expect(TOKEN_TYPES.CloseStatement, "Expected %} token");
|
||||
break;
|
||||
case "for":
|
||||
++current;
|
||||
result = parseForStatement();
|
||||
// expect {% endfor %}
|
||||
expect(TOKEN_TYPES.OpenStatement, "Expected {% token");
|
||||
expectIdentifier("endfor");
|
||||
expect(TOKEN_TYPES.CloseStatement, "Expected %} token");
|
||||
break;
|
||||
case "call": {
|
||||
++current; // consume 'call'
|
||||
let callerArgs: Statement[] | null = null;
|
||||
if (is(TOKEN_TYPES.OpenParen)) {
|
||||
// Optional caller arguments, e.g. {% call(user) dump_users(...) %}
|
||||
callerArgs = parseArgs();
|
||||
}
|
||||
const callee = parsePrimaryExpression();
|
||||
if (callee.type !== "Identifier") {
|
||||
throw new SyntaxError(`Expected identifier following call statement`);
|
||||
}
|
||||
const callArgs = parseArgs();
|
||||
expect(TOKEN_TYPES.CloseStatement, "Expected closing statement token");
|
||||
const body: Statement[] = [];
|
||||
while (!isStatement("endcall")) {
|
||||
body.push(parseAny());
|
||||
}
|
||||
expect(TOKEN_TYPES.OpenStatement, "Expected '{%'");
|
||||
expectIdentifier("endcall");
|
||||
expect(TOKEN_TYPES.CloseStatement, "Expected closing statement token");
|
||||
const callExpr = new CallExpression(callee, callArgs);
|
||||
result = new CallStatement(callExpr, callerArgs, body);
|
||||
break;
|
||||
}
|
||||
case "break":
|
||||
++current;
|
||||
expect(TOKEN_TYPES.CloseStatement, "Expected closing statement token");
|
||||
result = new Break();
|
||||
break;
|
||||
case "continue":
|
||||
++current;
|
||||
expect(TOKEN_TYPES.CloseStatement, "Expected closing statement token");
|
||||
result = new Continue();
|
||||
break;
|
||||
case "filter": {
|
||||
++current; // consume 'filter'
|
||||
let filterNode = parsePrimaryExpression();
|
||||
if (filterNode instanceof Identifier && is(TOKEN_TYPES.OpenParen)) {
|
||||
filterNode = parseCallExpression(filterNode);
|
||||
}
|
||||
expect(TOKEN_TYPES.CloseStatement, "Expected closing statement token");
|
||||
const filterBody: Statement[] = [];
|
||||
while (!isStatement("endfilter")) {
|
||||
filterBody.push(parseAny());
|
||||
}
|
||||
expect(TOKEN_TYPES.OpenStatement, "Expected '{%'");
|
||||
expectIdentifier("endfilter");
|
||||
expect(TOKEN_TYPES.CloseStatement, "Expected '%}'");
|
||||
result = new FilterStatement(filterNode as Identifier | CallExpression, filterBody);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new SyntaxError(`Unknown statement type: ${name}`);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function parseJinjaExpression(): Statement {
|
||||
// Consume {{ }} tokens
|
||||
expect(TOKEN_TYPES.OpenExpression, "Expected opening expression token");
|
||||
|
||||
const result = parseExpression();
|
||||
|
||||
expect(TOKEN_TYPES.CloseExpression, "Expected closing expression token");
|
||||
return result;
|
||||
}
|
||||
|
||||
// NOTE: `set` acts as both declaration statement and assignment expression
|
||||
function parseSetStatement(): Statement {
|
||||
const left = parseExpressionSequence();
|
||||
let value: Statement | null = null;
|
||||
const body: Statement[] = [];
|
||||
if (is(TOKEN_TYPES.Equals)) {
|
||||
++current;
|
||||
value = parseExpressionSequence();
|
||||
} else {
|
||||
// parsing multiline set here
|
||||
expect(TOKEN_TYPES.CloseStatement, "Expected %} token");
|
||||
while (!isStatement("endset")) {
|
||||
body.push(parseAny());
|
||||
}
|
||||
expect(TOKEN_TYPES.OpenStatement, "Expected {% token");
|
||||
expectIdentifier("endset");
|
||||
}
|
||||
expect(TOKEN_TYPES.CloseStatement, "Expected closing statement token");
|
||||
return new SetStatement(left, value, body);
|
||||
}
|
||||
|
||||
function parseIfStatement(): If {
|
||||
const test = parseExpression();
|
||||
|
||||
expect(TOKEN_TYPES.CloseStatement, "Expected closing statement token");
|
||||
|
||||
const body: Statement[] = [];
|
||||
const alternate: Statement[] = [];
|
||||
|
||||
// Keep parsing 'if' body until we reach the first {% elif %} or {% else %} or {% endif %}
|
||||
while (!isStatement("elif", "else", "endif")) {
|
||||
body.push(parseAny());
|
||||
}
|
||||
|
||||
// handle {% elif %}
|
||||
if (isStatement("elif")) {
|
||||
++current; // consume {%
|
||||
++current; // consume 'elif'
|
||||
const result = parseIfStatement(); // nested If
|
||||
alternate.push(result);
|
||||
}
|
||||
// handle {% else %}
|
||||
else if (isStatement("else")) {
|
||||
++current; // consume {%
|
||||
++current; // consume 'else'
|
||||
expect(TOKEN_TYPES.CloseStatement, "Expected closing statement token");
|
||||
|
||||
// keep going until we hit {% endif %}
|
||||
while (!isStatement("endif")) {
|
||||
alternate.push(parseAny());
|
||||
}
|
||||
}
|
||||
|
||||
return new If(test, body, alternate);
|
||||
}
|
||||
|
||||
function parseMacroStatement(): Macro {
|
||||
const name = parsePrimaryExpression();
|
||||
if (name.type !== "Identifier") {
|
||||
throw new SyntaxError(`Expected identifier following macro statement`);
|
||||
}
|
||||
const args = parseArgs();
|
||||
expect(TOKEN_TYPES.CloseStatement, "Expected closing statement token");
|
||||
|
||||
// Body of macro
|
||||
const body: Statement[] = [];
|
||||
|
||||
// Keep going until we hit {% endmacro
|
||||
while (!isStatement("endmacro")) {
|
||||
body.push(parseAny());
|
||||
}
|
||||
|
||||
return new Macro(name as Identifier, args, body);
|
||||
}
|
||||
|
||||
function parseExpressionSequence(primary = false): Statement {
|
||||
const fn = primary ? parsePrimaryExpression : parseExpression;
|
||||
const expressions = [fn()];
|
||||
const isTuple = is(TOKEN_TYPES.Comma);
|
||||
while (isTuple) {
|
||||
++current; // consume comma
|
||||
expressions.push(fn());
|
||||
if (!is(TOKEN_TYPES.Comma)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return isTuple ? new TupleLiteral(expressions) : expressions[0];
|
||||
}
|
||||
|
||||
function parseForStatement(): For {
|
||||
// e.g., `message` in `for message in messages`
|
||||
const loopVariable = parseExpressionSequence(true); // should be an identifier/tuple
|
||||
if (!(loopVariable instanceof Identifier || loopVariable instanceof TupleLiteral)) {
|
||||
throw new SyntaxError(`Expected identifier/tuple for the loop variable, got ${loopVariable.type} instead`);
|
||||
}
|
||||
|
||||
if (!isIdentifier("in")) {
|
||||
throw new SyntaxError("Expected `in` keyword following loop variable");
|
||||
}
|
||||
++current;
|
||||
|
||||
// `messages` in `for message in messages`
|
||||
const iterable = parseExpression();
|
||||
|
||||
expect(TOKEN_TYPES.CloseStatement, "Expected closing statement token");
|
||||
|
||||
// Body of for loop
|
||||
const body: Statement[] = [];
|
||||
|
||||
// Keep going until we hit {% endfor or {% else
|
||||
while (!isStatement("endfor", "else")) {
|
||||
body.push(parseAny());
|
||||
}
|
||||
|
||||
// (Optional) else block
|
||||
const alternative: Statement[] = [];
|
||||
if (isStatement("else")) {
|
||||
++current; // consume {%
|
||||
++current; // consume 'else'
|
||||
expect(TOKEN_TYPES.CloseStatement, "Expected closing statement token");
|
||||
while (!isStatement("endfor")) {
|
||||
alternative.push(parseAny());
|
||||
}
|
||||
}
|
||||
|
||||
return new For(loopVariable, iterable, body, alternative);
|
||||
}
|
||||
|
||||
function parseExpression(): Statement {
|
||||
// Choose parse function with lowest precedence
|
||||
return parseIfExpression();
|
||||
}
|
||||
|
||||
function parseIfExpression(): Statement {
|
||||
const a = parseLogicalOrExpression();
|
||||
if (isIdentifier("if")) {
|
||||
// Ternary expression
|
||||
++current; // consume 'if'
|
||||
const test = parseLogicalOrExpression();
|
||||
|
||||
if (isIdentifier("else")) {
|
||||
// Ternary expression with else
|
||||
++current; // consume 'else'
|
||||
const falseExpr = parseIfExpression(); // recurse to support chained ternaries
|
||||
return new Ternary(test, a, falseExpr);
|
||||
} else {
|
||||
// Select expression on iterable
|
||||
return new SelectExpression(a, test);
|
||||
}
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
function parseLogicalOrExpression(): Statement {
|
||||
let left = parseLogicalAndExpression();
|
||||
while (isIdentifier("or")) {
|
||||
const operator = tokens[current];
|
||||
++current;
|
||||
const right = parseLogicalAndExpression();
|
||||
left = new BinaryExpression(operator, left, right);
|
||||
}
|
||||
return left;
|
||||
}
|
||||
|
||||
function parseLogicalAndExpression(): Statement {
|
||||
let left = parseLogicalNegationExpression();
|
||||
while (isIdentifier("and")) {
|
||||
const operator = tokens[current];
|
||||
++current;
|
||||
const right = parseLogicalNegationExpression();
|
||||
left = new BinaryExpression(operator, left, right);
|
||||
}
|
||||
return left;
|
||||
}
|
||||
|
||||
function parseLogicalNegationExpression(): Statement {
|
||||
let right: UnaryExpression | undefined;
|
||||
|
||||
// Try parse unary operators
|
||||
while (isIdentifier("not")) {
|
||||
// not not ...
|
||||
const operator = tokens[current];
|
||||
++current;
|
||||
const arg = parseLogicalNegationExpression(); // not test.x === not (test.x)
|
||||
right = new UnaryExpression(operator, arg);
|
||||
}
|
||||
|
||||
return right ?? parseComparisonExpression();
|
||||
}
|
||||
|
||||
function parseComparisonExpression(): Statement {
|
||||
// NOTE: membership has same precedence as comparison
|
||||
// e.g., ('a' in 'apple' == 'b' in 'banana') evaluates as ('a' in ('apple' == ('b' in 'banana')))
|
||||
let left = parseAdditiveExpression();
|
||||
while (true) {
|
||||
let operator: Token;
|
||||
if (isIdentifier("not", "in")) {
|
||||
operator = new Token("not in", TOKEN_TYPES.Identifier);
|
||||
current += 2;
|
||||
} else if (isIdentifier("in")) {
|
||||
operator = tokens[current++];
|
||||
} else if (is(TOKEN_TYPES.ComparisonBinaryOperator)) {
|
||||
operator = tokens[current++];
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
const right = parseAdditiveExpression();
|
||||
left = new BinaryExpression(operator, left, right);
|
||||
}
|
||||
return left;
|
||||
}
|
||||
function parseAdditiveExpression(): Statement {
|
||||
let left = parseMultiplicativeExpression();
|
||||
while (is(TOKEN_TYPES.AdditiveBinaryOperator)) {
|
||||
const operator = tokens[current];
|
||||
++current;
|
||||
const right = parseMultiplicativeExpression();
|
||||
left = new BinaryExpression(operator, left, right);
|
||||
}
|
||||
return left;
|
||||
}
|
||||
|
||||
function parseCallMemberExpression(): Statement {
|
||||
// Handle member expressions recursively
|
||||
|
||||
const member = parseMemberExpression(parsePrimaryExpression()); // foo.x
|
||||
|
||||
if (is(TOKEN_TYPES.OpenParen)) {
|
||||
// foo.x()
|
||||
return parseCallExpression(member);
|
||||
}
|
||||
return member;
|
||||
}
|
||||
|
||||
function parseCallExpression(callee: Statement): Statement {
|
||||
let expression: Statement = new CallExpression(callee, parseArgs());
|
||||
|
||||
expression = parseMemberExpression(expression); // foo.x().y
|
||||
|
||||
if (is(TOKEN_TYPES.OpenParen)) {
|
||||
// foo.x()()
|
||||
expression = parseCallExpression(expression);
|
||||
}
|
||||
|
||||
return expression;
|
||||
}
|
||||
|
||||
function parseArgs(): Statement[] {
|
||||
// add (x + 5, foo())
|
||||
expect(TOKEN_TYPES.OpenParen, "Expected opening parenthesis for arguments list");
|
||||
|
||||
const args = parseArgumentsList();
|
||||
|
||||
expect(TOKEN_TYPES.CloseParen, "Expected closing parenthesis for arguments list");
|
||||
return args;
|
||||
}
|
||||
function parseArgumentsList(): Statement[] {
|
||||
// comma-separated arguments list
|
||||
|
||||
const args = [];
|
||||
while (!is(TOKEN_TYPES.CloseParen)) {
|
||||
let argument: Statement;
|
||||
|
||||
// unpacking: *expr
|
||||
if (tokens[current].type === TOKEN_TYPES.MultiplicativeBinaryOperator && tokens[current].value === "*") {
|
||||
++current;
|
||||
const expr = parseExpression();
|
||||
argument = new SpreadExpression(expr);
|
||||
} else {
|
||||
argument = parseExpression();
|
||||
if (is(TOKEN_TYPES.Equals)) {
|
||||
// keyword argument
|
||||
// e.g., func(x = 5, y = a or b)
|
||||
++current; // consume equals
|
||||
if (!(argument instanceof Identifier)) {
|
||||
throw new SyntaxError(`Expected identifier for keyword argument`);
|
||||
}
|
||||
const value = parseExpression();
|
||||
argument = new KeywordArgumentExpression(argument as Identifier, value);
|
||||
}
|
||||
}
|
||||
args.push(argument);
|
||||
if (is(TOKEN_TYPES.Comma)) {
|
||||
++current; // consume comma
|
||||
}
|
||||
}
|
||||
return args;
|
||||
}
|
||||
|
||||
function parseMemberExpressionArgumentsList(): Statement {
|
||||
// NOTE: This also handles slice expressions colon-separated arguments list
|
||||
// e.g., ['test'], [0], [:2], [1:], [1:2], [1:2:3]
|
||||
|
||||
const slices: (Statement | undefined)[] = [];
|
||||
let isSlice = false;
|
||||
while (!is(TOKEN_TYPES.CloseSquareBracket)) {
|
||||
if (is(TOKEN_TYPES.Colon)) {
|
||||
// A case where a default is used
|
||||
// e.g., [:2] will be parsed as [undefined, 2]
|
||||
slices.push(undefined);
|
||||
++current; // consume colon
|
||||
isSlice = true;
|
||||
} else {
|
||||
slices.push(parseExpression());
|
||||
if (is(TOKEN_TYPES.Colon)) {
|
||||
++current; // consume colon after expression, if it exists
|
||||
isSlice = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (slices.length === 0) {
|
||||
// []
|
||||
throw new SyntaxError(`Expected at least one argument for member/slice expression`);
|
||||
}
|
||||
|
||||
if (isSlice) {
|
||||
if (slices.length > 3) {
|
||||
throw new SyntaxError(`Expected 0-3 arguments for slice expression`);
|
||||
}
|
||||
return new SliceExpression(...slices);
|
||||
}
|
||||
|
||||
return slices[0] as Statement; // normal member expression
|
||||
}
|
||||
|
||||
function parseMemberExpression(object: Statement): Statement {
|
||||
while (is(TOKEN_TYPES.Dot) || is(TOKEN_TYPES.OpenSquareBracket)) {
|
||||
const operator = tokens[current]; // . or [
|
||||
++current;
|
||||
let property: Statement;
|
||||
const computed = operator.type === TOKEN_TYPES.OpenSquareBracket;
|
||||
if (computed) {
|
||||
// computed (i.e., bracket notation: obj[expr])
|
||||
property = parseMemberExpressionArgumentsList();
|
||||
expect(TOKEN_TYPES.CloseSquareBracket, "Expected closing square bracket");
|
||||
} else {
|
||||
// non-computed (i.e., dot notation: obj.expr)
|
||||
property = parsePrimaryExpression(); // should be an identifier
|
||||
if (property.type !== "Identifier") {
|
||||
throw new SyntaxError(`Expected identifier following dot operator`);
|
||||
}
|
||||
}
|
||||
object = new MemberExpression(object, property, computed);
|
||||
}
|
||||
return object;
|
||||
}
|
||||
|
||||
function parseMultiplicativeExpression(): Statement {
|
||||
let left = parseTestExpression();
|
||||
|
||||
// Multiplicative operators have higher precedence than test expressions
|
||||
// e.g., (4 * 4 is divisibleby(2)) evaluates as (4 * (4 is divisibleby(2)))
|
||||
|
||||
while (is(TOKEN_TYPES.MultiplicativeBinaryOperator)) {
|
||||
const operator = tokens[current++];
|
||||
const right = parseTestExpression();
|
||||
left = new BinaryExpression(operator, left, right);
|
||||
}
|
||||
return left;
|
||||
}
|
||||
|
||||
function parseTestExpression(): Statement {
|
||||
let operand = parseFilterExpression();
|
||||
|
||||
while (isIdentifier("is")) {
|
||||
// Support chaining tests
|
||||
++current; // consume is
|
||||
const negate = isIdentifier("not");
|
||||
if (negate) {
|
||||
++current; // consume not
|
||||
}
|
||||
|
||||
const filter = parsePrimaryExpression();
|
||||
if (!(filter instanceof Identifier)) {
|
||||
throw new SyntaxError(`Expected identifier for the test`);
|
||||
}
|
||||
// TODO: Add support for non-identifier tests
|
||||
operand = new TestExpression(operand, negate, filter);
|
||||
}
|
||||
return operand;
|
||||
}
|
||||
|
||||
function parseFilterExpression(): Statement {
|
||||
let operand = parseCallMemberExpression();
|
||||
|
||||
while (is(TOKEN_TYPES.Pipe)) {
|
||||
// Support chaining filters
|
||||
++current; // consume pipe
|
||||
let filter = parsePrimaryExpression(); // should be an identifier
|
||||
if (!(filter instanceof Identifier)) {
|
||||
throw new SyntaxError(`Expected identifier for the filter`);
|
||||
}
|
||||
if (is(TOKEN_TYPES.OpenParen)) {
|
||||
filter = parseCallExpression(filter);
|
||||
}
|
||||
operand = new FilterExpression(operand, filter as Identifier | CallExpression);
|
||||
}
|
||||
return operand;
|
||||
}
|
||||
|
||||
function parsePrimaryExpression(): Statement {
|
||||
// Primary expression: number, string, identifier, function call, parenthesized expression
|
||||
const token = tokens[current++];
|
||||
switch (token.type) {
|
||||
case TOKEN_TYPES.NumericLiteral: {
|
||||
const num = token.value;
|
||||
return num.includes(".") ? new FloatLiteral(Number(num)) : new IntegerLiteral(Number(num));
|
||||
}
|
||||
case TOKEN_TYPES.StringLiteral: {
|
||||
let value = token.value;
|
||||
while (is(TOKEN_TYPES.StringLiteral)) {
|
||||
value += tokens[current++].value;
|
||||
}
|
||||
return new StringLiteral(value);
|
||||
}
|
||||
case TOKEN_TYPES.Identifier:
|
||||
return new Identifier(token.value);
|
||||
case TOKEN_TYPES.OpenParen: {
|
||||
const expression = parseExpressionSequence();
|
||||
expect(TOKEN_TYPES.CloseParen, "Expected closing parenthesis, got ${tokens[current].type} instead.");
|
||||
return expression;
|
||||
}
|
||||
case TOKEN_TYPES.OpenSquareBracket: {
|
||||
const values = [];
|
||||
while (!is(TOKEN_TYPES.CloseSquareBracket)) {
|
||||
values.push(parseExpression());
|
||||
|
||||
if (is(TOKEN_TYPES.Comma)) {
|
||||
++current; // consume comma
|
||||
}
|
||||
}
|
||||
++current; // consume closing square bracket
|
||||
|
||||
return new ArrayLiteral(values);
|
||||
}
|
||||
case TOKEN_TYPES.OpenCurlyBracket: {
|
||||
const values = new Map();
|
||||
while (!is(TOKEN_TYPES.CloseCurlyBracket)) {
|
||||
const key = parseExpression();
|
||||
expect(TOKEN_TYPES.Colon, "Expected colon between key and value in object literal");
|
||||
const value = parseExpression();
|
||||
values.set(key, value);
|
||||
|
||||
if (is(TOKEN_TYPES.Comma)) {
|
||||
++current; // consume comma
|
||||
}
|
||||
}
|
||||
++current; // consume closing curly bracket
|
||||
|
||||
return new ObjectLiteral(values);
|
||||
}
|
||||
default:
|
||||
throw new SyntaxError(`Unexpected token: ${token.type}`);
|
||||
}
|
||||
}
|
||||
|
||||
while (current < tokens.length) {
|
||||
program.body.push(parseAny());
|
||||
}
|
||||
|
||||
return program;
|
||||
}
|
||||
1880
node_modules/@huggingface/jinja/src/runtime.ts
generated
vendored
Normal file
1880
node_modules/@huggingface/jinja/src/runtime.ts
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
123
node_modules/@huggingface/jinja/src/utils.ts
generated
vendored
Normal file
123
node_modules/@huggingface/jinja/src/utils.ts
generated
vendored
Normal file
@@ -0,0 +1,123 @@
|
||||
/**
|
||||
* Function that mimics Python's range() function.
|
||||
* @param start The start value of the range.
|
||||
* @param stop The stop value of the range. If not provided, start will be 0 and stop will be the provided start value.
|
||||
* @param step The step value of the range. Defaults to 1.
|
||||
* @returns The range of numbers.
|
||||
*/
|
||||
export function range(start: number, stop?: number, step = 1): number[] {
|
||||
if (stop === undefined) {
|
||||
stop = start;
|
||||
start = 0;
|
||||
}
|
||||
|
||||
if (step === 0) {
|
||||
throw new Error("range() step must not be zero");
|
||||
}
|
||||
|
||||
const result: number[] = [];
|
||||
if (step > 0) {
|
||||
for (let i = start; i < stop; i += step) {
|
||||
result.push(i);
|
||||
}
|
||||
} else {
|
||||
for (let i = start; i > stop; i += step) {
|
||||
result.push(i);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function that mimics Python's array slicing.
|
||||
* @param array The array to slice.
|
||||
* @param start The start index of the slice. Defaults to 0.
|
||||
* @param stop The last index of the slice. Defaults to `array.length`.
|
||||
* @param step The step value of the slice. Defaults to 1.
|
||||
* @returns The sliced array.
|
||||
*/
|
||||
export function slice<T>(array: T[], start?: number, stop?: number, step = 1): T[] {
|
||||
const direction = Math.sign(step);
|
||||
|
||||
if (direction >= 0) {
|
||||
start = (start ??= 0) < 0 ? Math.max(array.length + start, 0) : Math.min(start, array.length);
|
||||
stop = (stop ??= array.length) < 0 ? Math.max(array.length + stop, 0) : Math.min(stop, array.length);
|
||||
} else {
|
||||
start = (start ??= array.length - 1) < 0 ? Math.max(array.length + start, -1) : Math.min(start, array.length - 1);
|
||||
stop = (stop ??= -1) < -1 ? Math.max(array.length + stop, -1) : Math.min(stop, array.length - 1);
|
||||
}
|
||||
|
||||
const result: T[] = [];
|
||||
for (let i = start; direction * i < direction * stop; i += step) {
|
||||
result.push(array[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function that mimics Python's string.title() function.
|
||||
* @param value The string to title case.
|
||||
* @returns The title cased string.
|
||||
*/
|
||||
export function titleCase(value: string): string {
|
||||
return value.replace(/\b\w/g, (c) => c.toUpperCase());
|
||||
}
|
||||
|
||||
export function strftime_now(format: string): string {
|
||||
return strftime(new Date(), format);
|
||||
}
|
||||
|
||||
/**
|
||||
* A minimalistic implementation of Python's strftime function.
|
||||
*/
|
||||
export function strftime(date: Date, format: string): string {
|
||||
// Set locale to undefined to use the default locale
|
||||
const monthFormatterLong = new Intl.DateTimeFormat(undefined, { month: "long" });
|
||||
const monthFormatterShort = new Intl.DateTimeFormat(undefined, { month: "short" });
|
||||
|
||||
const pad2 = (n: number): string => (n < 10 ? "0" + n : n.toString());
|
||||
|
||||
return format.replace(/%[YmdbBHM%]/g, (token) => {
|
||||
switch (token) {
|
||||
case "%Y":
|
||||
return date.getFullYear().toString();
|
||||
case "%m":
|
||||
return pad2(date.getMonth() + 1);
|
||||
case "%d":
|
||||
return pad2(date.getDate());
|
||||
case "%b":
|
||||
return monthFormatterShort.format(date);
|
||||
case "%B":
|
||||
return monthFormatterLong.format(date);
|
||||
case "%H":
|
||||
return pad2(date.getHours());
|
||||
case "%M":
|
||||
return pad2(date.getMinutes());
|
||||
case "%%":
|
||||
return "%";
|
||||
default:
|
||||
return token;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function escapeRegExp(s: string): string {
|
||||
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
||||
}
|
||||
|
||||
/**
|
||||
* Function that mimics Python's string.replace() function.
|
||||
*/
|
||||
export function replace(str: string, oldvalue: string, newvalue: string, count?: number | null): string {
|
||||
if (count === 0) return str;
|
||||
let remaining = count == null || count < 0 ? Infinity : count;
|
||||
// NB: Use a Unicode-aware global regex so unpaired surrogates won't match
|
||||
const pattern = oldvalue.length === 0 ? new RegExp("(?=)", "gu") : new RegExp(escapeRegExp(oldvalue), "gu");
|
||||
return str.replaceAll(pattern, (match) => {
|
||||
if (remaining > 0) {
|
||||
--remaining;
|
||||
return newvalue;
|
||||
}
|
||||
return match;
|
||||
});
|
||||
}
|
||||
20
node_modules/@huggingface/jinja/tsconfig.json
generated
vendored
Normal file
20
node_modules/@huggingface/jinja/tsconfig.json
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"lib": ["ES2022", "DOM"],
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "node",
|
||||
"target": "ESNext",
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"noImplicitAny": true,
|
||||
"strictNullChecks": true,
|
||||
"skipLibCheck": true,
|
||||
"noImplicitOverride": true,
|
||||
"outDir": "./dist",
|
||||
"declaration": true,
|
||||
"declarationMap": true
|
||||
},
|
||||
"include": ["src", "index.ts"],
|
||||
"exclude": ["dist"]
|
||||
}
|
||||
Reference in New Issue
Block a user