Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
machineuser
commited on
Commit
·
ca548dc
1
Parent(s):
803a700
Sync widgets demo
Browse files- packages/inference/README.md +15 -0
- packages/inference/package.json +1 -1
- packages/inference/src/lib/makeRequestOptions.ts +19 -11
- packages/inference/src/tasks/custom/streamingRequest.ts +1 -1
- packages/jinja/package.json +1 -1
- packages/jinja/src/ast.ts +8 -1
- packages/jinja/src/parser.ts +25 -6
- packages/jinja/src/runtime.ts +52 -1
- packages/jinja/test/e2e.test.js +40 -0
- packages/jinja/test/templates.test.js +126 -0
- packages/tasks/src/model-libraries.ts +3 -3
packages/inference/README.md
CHANGED
@@ -506,6 +506,21 @@ const gpt2 = hf.endpoint('https://xyz.eu-west-1.aws.endpoints.huggingface.cloud/
|
|
506 |
const { generated_text } = await gpt2.textGeneration({inputs: 'The answer to the universe is'});
|
507 |
```
|
508 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
509 |
## Running tests
|
510 |
|
511 |
```console
|
|
|
506 |
const { generated_text } = await gpt2.textGeneration({inputs: 'The answer to the universe is'});
|
507 |
```
|
508 |
|
509 |
+
By default, all calls to the inference endpoint will wait until the model is
|
510 |
+
loaded. When [scaling to
|
511 |
+
0](https://huggingface.co/docs/inference-endpoints/en/autoscaling#scaling-to-0)
|
512 |
+
is enabled on the endpoint, this can result in non-trivial waiting time. If
|
513 |
+
you'd rather disable this behavior and handle the endpoint's returned 500 HTTP
|
514 |
+
errors yourself, you can do so like so:
|
515 |
+
|
516 |
+
```typescript
|
517 |
+
const gpt2 = hf.endpoint('https://xyz.eu-west-1.aws.endpoints.huggingface.cloud/gpt2');
|
518 |
+
const { generated_text } = await gpt2.textGeneration(
|
519 |
+
{inputs: 'The answer to the universe is'},
|
520 |
+
{retry_on_error: false},
|
521 |
+
);
|
522 |
+
```
|
523 |
+
|
524 |
## Running tests
|
525 |
|
526 |
```console
|
packages/inference/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
{
|
2 |
"name": "@huggingface/inference",
|
3 |
-
"version": "2.6.
|
4 |
"packageManager": "pnpm@8.10.5",
|
5 |
"license": "MIT",
|
6 |
"author": "Tim Mikeladze <tim.mikeladze@gmail.com>",
|
|
|
1 |
{
|
2 |
"name": "@huggingface/inference",
|
3 |
+
"version": "2.6.6",
|
4 |
"packageManager": "pnpm@8.10.5",
|
5 |
"license": "MIT",
|
6 |
"author": "Tim Mikeladze <tim.mikeladze@gmail.com>",
|
packages/inference/src/lib/makeRequestOptions.ts
CHANGED
@@ -27,7 +27,15 @@ export async function makeRequestOptions(
|
|
27 |
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
28 |
const { accessToken, model: _model, ...otherArgs } = args;
|
29 |
let { model } = args;
|
30 |
-
const {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
31 |
|
32 |
const headers: Record<string, string> = {};
|
33 |
if (accessToken) {
|
@@ -57,16 +65,16 @@ export async function makeRequestOptions(
|
|
57 |
|
58 |
if (!binary) {
|
59 |
headers["Content-Type"] = "application/json";
|
60 |
-
}
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
}
|
71 |
|
72 |
const url = (() => {
|
|
|
27 |
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
28 |
const { accessToken, model: _model, ...otherArgs } = args;
|
29 |
let { model } = args;
|
30 |
+
const {
|
31 |
+
forceTask: task,
|
32 |
+
includeCredentials,
|
33 |
+
taskHint,
|
34 |
+
wait_for_model,
|
35 |
+
use_cache,
|
36 |
+
dont_load_model,
|
37 |
+
...otherOptions
|
38 |
+
} = options ?? {};
|
39 |
|
40 |
const headers: Record<string, string> = {};
|
41 |
if (accessToken) {
|
|
|
65 |
|
66 |
if (!binary) {
|
67 |
headers["Content-Type"] = "application/json";
|
68 |
+
}
|
69 |
+
|
70 |
+
if (wait_for_model) {
|
71 |
+
headers["X-Wait-For-Model"] = "true";
|
72 |
+
}
|
73 |
+
if (use_cache === false) {
|
74 |
+
headers["X-Use-Cache"] = "false";
|
75 |
+
}
|
76 |
+
if (dont_load_model) {
|
77 |
+
headers["X-Load-Model"] = "0";
|
78 |
}
|
79 |
|
80 |
const url = (() => {
|
packages/inference/src/tasks/custom/streamingRequest.ts
CHANGED
@@ -19,7 +19,7 @@ export async function* streamingRequest<T>(
|
|
19 |
const response = await (options?.fetch ?? fetch)(url, info);
|
20 |
|
21 |
if (options?.retry_on_error !== false && response.status === 503 && !options?.wait_for_model) {
|
22 |
-
return streamingRequest(args, {
|
23 |
...options,
|
24 |
wait_for_model: true,
|
25 |
});
|
|
|
19 |
const response = await (options?.fetch ?? fetch)(url, info);
|
20 |
|
21 |
if (options?.retry_on_error !== false && response.status === 503 && !options?.wait_for_model) {
|
22 |
+
return yield* streamingRequest(args, {
|
23 |
...options,
|
24 |
wait_for_model: true,
|
25 |
});
|
packages/jinja/package.json
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
{
|
2 |
"name": "@huggingface/jinja",
|
3 |
"packageManager": "pnpm@8.10.5",
|
4 |
-
"version": "0.2.
|
5 |
"description": "A minimalistic JavaScript implementation of the Jinja templating engine, specifically designed for parsing and rendering ML chat templates.",
|
6 |
"repository": "https://github.com/huggingface/huggingface.js.git",
|
7 |
"publishConfig": {
|
|
|
1 |
{
|
2 |
"name": "@huggingface/jinja",
|
3 |
"packageManager": "pnpm@8.10.5",
|
4 |
+
"version": "0.2.2",
|
5 |
"description": "A minimalistic JavaScript implementation of the Jinja templating engine, specifically designed for parsing and rendering ML chat templates.",
|
6 |
"repository": "https://github.com/huggingface/huggingface.js.git",
|
7 |
"publishConfig": {
|
packages/jinja/src/ast.ts
CHANGED
@@ -34,7 +34,7 @@ export class For extends Statement {
|
|
34 |
override type = "For";
|
35 |
|
36 |
constructor(
|
37 |
-
public loopvar: Identifier,
|
38 |
public iterable: Expression,
|
39 |
public body: Statement[]
|
40 |
) {
|
@@ -136,6 +136,13 @@ export class ArrayLiteral extends Literal<Expression[]> {
|
|
136 |
override type = "ArrayLiteral";
|
137 |
}
|
138 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
139 |
/**
|
140 |
* Represents an object literal in the template.
|
141 |
*/
|
|
|
34 |
override type = "For";
|
35 |
|
36 |
constructor(
|
37 |
+
public loopvar: Identifier | TupleLiteral,
|
38 |
public iterable: Expression,
|
39 |
public body: Statement[]
|
40 |
) {
|
|
|
136 |
override type = "ArrayLiteral";
|
137 |
}
|
138 |
|
139 |
+
/**
|
140 |
+
* Represents a tuple literal in the template.
|
141 |
+
*/
|
142 |
+
export class TupleLiteral extends Literal<Expression[]> {
|
143 |
+
override type = "TupleLiteral";
|
144 |
+
}
|
145 |
+
|
146 |
/**
|
147 |
* Represents an object literal in the template.
|
148 |
*/
|
packages/jinja/src/parser.ts
CHANGED
@@ -20,6 +20,7 @@ import {
|
|
20 |
UnaryExpression,
|
21 |
SliceExpression,
|
22 |
KeywordArgumentExpression,
|
|
|
23 |
} from "./ast";
|
24 |
|
25 |
/**
|
@@ -172,16 +173,30 @@ export function parse(tokens: Token[]): Program {
|
|
172 |
return new If(test, body, alternate);
|
173 |
}
|
174 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
175 |
function parseForStatement(): For {
|
176 |
// e.g., `message` in `for message in messages`
|
177 |
-
const loopVariable =
|
178 |
-
if (!(loopVariable instanceof Identifier)) {
|
179 |
-
throw new SyntaxError(`Expected identifier for the loop variable`);
|
180 |
}
|
181 |
|
182 |
expect(TOKEN_TYPES.In, "Expected `in` keyword following loop variable");
|
183 |
|
184 |
-
// messages in `for message in messages`
|
185 |
const iterable = parseExpression();
|
186 |
|
187 |
expect(TOKEN_TYPES.CloseStatement, "Expected closing statement token");
|
@@ -199,6 +214,10 @@ export function parse(tokens: Token[]): Program {
|
|
199 |
|
200 |
function parseExpression(): Statement {
|
201 |
// Choose parse function with lowest precedence
|
|
|
|
|
|
|
|
|
202 |
const a = parseLogicalOrExpression();
|
203 |
if (is(TOKEN_TYPES.If)) {
|
204 |
// Ternary expression
|
@@ -464,9 +483,9 @@ export function parse(tokens: Token[]): Program {
|
|
464 |
return new Identifier(token.value);
|
465 |
case TOKEN_TYPES.OpenParen: {
|
466 |
++current; // consume opening parenthesis
|
467 |
-
const expression =
|
468 |
if (tokens[current].type !== TOKEN_TYPES.CloseParen) {
|
469 |
-
throw new SyntaxError(
|
470 |
}
|
471 |
++current; // consume closing parenthesis
|
472 |
return expression;
|
|
|
20 |
UnaryExpression,
|
21 |
SliceExpression,
|
22 |
KeywordArgumentExpression,
|
23 |
+
TupleLiteral,
|
24 |
} from "./ast";
|
25 |
|
26 |
/**
|
|
|
173 |
return new If(test, body, alternate);
|
174 |
}
|
175 |
|
176 |
+
function parseExpressionSequence(primary = false): Statement {
|
177 |
+
const fn = primary ? parsePrimaryExpression : parseExpression;
|
178 |
+
const expressions = [fn()];
|
179 |
+
const isTuple = is(TOKEN_TYPES.Comma);
|
180 |
+
while (isTuple) {
|
181 |
+
++current; // consume comma
|
182 |
+
expressions.push(fn());
|
183 |
+
if (!is(TOKEN_TYPES.Comma)) {
|
184 |
+
break;
|
185 |
+
}
|
186 |
+
}
|
187 |
+
return isTuple ? new TupleLiteral(expressions) : expressions[0];
|
188 |
+
}
|
189 |
+
|
190 |
function parseForStatement(): For {
|
191 |
// e.g., `message` in `for message in messages`
|
192 |
+
const loopVariable = parseExpressionSequence(true); // should be an identifier
|
193 |
+
if (!(loopVariable instanceof Identifier || loopVariable instanceof TupleLiteral)) {
|
194 |
+
throw new SyntaxError(`Expected identifier/tuple for the loop variable, got ${loopVariable.type} instead`);
|
195 |
}
|
196 |
|
197 |
expect(TOKEN_TYPES.In, "Expected `in` keyword following loop variable");
|
198 |
|
199 |
+
// `messages` in `for message in messages`
|
200 |
const iterable = parseExpression();
|
201 |
|
202 |
expect(TOKEN_TYPES.CloseStatement, "Expected closing statement token");
|
|
|
214 |
|
215 |
function parseExpression(): Statement {
|
216 |
// Choose parse function with lowest precedence
|
217 |
+
return parseTernaryExpression();
|
218 |
+
}
|
219 |
+
|
220 |
+
function parseTernaryExpression(): Statement {
|
221 |
const a = parseLogicalOrExpression();
|
222 |
if (is(TOKEN_TYPES.If)) {
|
223 |
// Ternary expression
|
|
|
483 |
return new Identifier(token.value);
|
484 |
case TOKEN_TYPES.OpenParen: {
|
485 |
++current; // consume opening parenthesis
|
486 |
+
const expression = parseExpressionSequence();
|
487 |
if (tokens[current].type !== TOKEN_TYPES.CloseParen) {
|
488 |
+
throw new SyntaxError(`Expected closing parenthesis, got ${tokens[current].type} instead`);
|
489 |
}
|
490 |
++current; // consume closing parenthesis
|
491 |
return expression;
|
packages/jinja/src/runtime.ts
CHANGED
@@ -18,6 +18,7 @@ import type {
|
|
18 |
SliceExpression,
|
19 |
KeywordArgumentExpression,
|
20 |
ObjectLiteral,
|
|
|
21 |
} from "./ast";
|
22 |
import { slice, titleCase } from "./utils";
|
23 |
|
@@ -138,6 +139,14 @@ export class ObjectValue extends RuntimeValue<Map<string, AnyRuntimeValue>> {
|
|
138 |
return this.value.get(key.value) ?? defaultValue ?? new NullValue();
|
139 |
}),
|
140 |
],
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
141 |
]);
|
142 |
}
|
143 |
|
@@ -161,6 +170,14 @@ export class ArrayValue extends RuntimeValue<AnyRuntimeValue[]> {
|
|
161 |
}
|
162 |
}
|
163 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
164 |
/**
|
165 |
* Represents a Function value at runtime.
|
166 |
*/
|
@@ -500,6 +517,17 @@ export class Interpreter {
|
|
500 |
default:
|
501 |
throw new Error(`Unknown NumericValue filter: ${filter.value}`);
|
502 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
503 |
}
|
504 |
throw new Error(`Cannot apply filter "${filter.value}" to type: ${operand.type}`);
|
505 |
} else if (node.filter.type === "CallExpression") {
|
@@ -763,8 +791,29 @@ export class Interpreter {
|
|
763 |
|
764 |
scope.setVariable("loop", new ObjectValue(loop));
|
765 |
|
|
|
|
|
766 |
// For this iteration, set the loop variable to the current element
|
767 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
768 |
|
769 |
// Evaluate the body of the for loop
|
770 |
const evaluated = this.evaluateBlock(node.body, scope);
|
@@ -799,6 +848,8 @@ export class Interpreter {
|
|
799 |
return new BooleanValue((statement as BooleanLiteral).value);
|
800 |
case "ArrayLiteral":
|
801 |
return new ArrayValue((statement as ArrayLiteral).value.map((x) => this.evaluate(x, environment)));
|
|
|
|
|
802 |
case "ObjectLiteral": {
|
803 |
const mapping = new Map();
|
804 |
for (const [key, value] of (statement as ObjectLiteral).value) {
|
|
|
18 |
SliceExpression,
|
19 |
KeywordArgumentExpression,
|
20 |
ObjectLiteral,
|
21 |
+
TupleLiteral,
|
22 |
} from "./ast";
|
23 |
import { slice, titleCase } from "./utils";
|
24 |
|
|
|
139 |
return this.value.get(key.value) ?? defaultValue ?? new NullValue();
|
140 |
}),
|
141 |
],
|
142 |
+
[
|
143 |
+
"items",
|
144 |
+
new FunctionValue(() => {
|
145 |
+
return new ArrayValue(
|
146 |
+
Array.from(this.value.entries()).map(([key, value]) => new ArrayValue([new StringValue(key), value]))
|
147 |
+
);
|
148 |
+
}),
|
149 |
+
],
|
150 |
]);
|
151 |
}
|
152 |
|
|
|
170 |
}
|
171 |
}
|
172 |
|
173 |
+
/**
|
174 |
+
* Represents a Tuple value at runtime.
|
175 |
+
* NOTE: We extend ArrayValue since JavaScript does not have a built-in Tuple type.
|
176 |
+
*/
|
177 |
+
export class TupleValue extends ArrayValue {
|
178 |
+
override type = "TupleValue";
|
179 |
+
}
|
180 |
+
|
181 |
/**
|
182 |
* Represents a Function value at runtime.
|
183 |
*/
|
|
|
517 |
default:
|
518 |
throw new Error(`Unknown NumericValue filter: ${filter.value}`);
|
519 |
}
|
520 |
+
} else if (operand instanceof ObjectValue) {
|
521 |
+
switch (filter.value) {
|
522 |
+
case "items":
|
523 |
+
return new ArrayValue(
|
524 |
+
Array.from(operand.value.entries()).map(([key, value]) => new ArrayValue([new StringValue(key), value]))
|
525 |
+
);
|
526 |
+
case "length":
|
527 |
+
return new NumericValue(operand.value.size);
|
528 |
+
default:
|
529 |
+
throw new Error(`Unknown ObjectValue filter: ${filter.value}`);
|
530 |
+
}
|
531 |
}
|
532 |
throw new Error(`Cannot apply filter "${filter.value}" to type: ${operand.type}`);
|
533 |
} else if (node.filter.type === "CallExpression") {
|
|
|
791 |
|
792 |
scope.setVariable("loop", new ObjectValue(loop));
|
793 |
|
794 |
+
const current = iterable.value[i];
|
795 |
+
|
796 |
// For this iteration, set the loop variable to the current element
|
797 |
+
if (node.loopvar.type === "Identifier") {
|
798 |
+
scope.setVariable((node.loopvar as Identifier).value, current);
|
799 |
+
} else if (node.loopvar.type === "TupleLiteral") {
|
800 |
+
const loopvar = node.loopvar as TupleLiteral;
|
801 |
+
if (current.type !== "ArrayValue") {
|
802 |
+
throw new Error(`Cannot unpack non-iterable type: ${current.type}`);
|
803 |
+
}
|
804 |
+
const c = current as ArrayValue;
|
805 |
+
|
806 |
+
// check if too few or many items to unpack
|
807 |
+
if (loopvar.value.length !== c.value.length) {
|
808 |
+
throw new Error(`Too ${loopvar.value.length > c.value.length ? "few" : "many"} items to unpack`);
|
809 |
+
}
|
810 |
+
for (let j = 0; j < loopvar.value.length; ++j) {
|
811 |
+
if (loopvar.value[j].type !== "Identifier") {
|
812 |
+
throw new Error(`Cannot unpack non-identifier type: ${loopvar.value[j].type}`);
|
813 |
+
}
|
814 |
+
scope.setVariable((loopvar.value[j] as Identifier).value, c.value[j]);
|
815 |
+
}
|
816 |
+
}
|
817 |
|
818 |
// Evaluate the body of the for loop
|
819 |
const evaluated = this.evaluateBlock(node.body, scope);
|
|
|
848 |
return new BooleanValue((statement as BooleanLiteral).value);
|
849 |
case "ArrayLiteral":
|
850 |
return new ArrayValue((statement as ArrayLiteral).value.map((x) => this.evaluate(x, environment)));
|
851 |
+
case "TupleLiteral":
|
852 |
+
return new TupleValue((statement as TupleLiteral).value.map((x) => this.evaluate(x, environment)));
|
853 |
case "ObjectLiteral": {
|
854 |
const mapping = new Map();
|
855 |
for (const [key, value] of (statement as ObjectLiteral).value) {
|
packages/jinja/test/e2e.test.js
CHANGED
@@ -376,6 +376,46 @@ const TEST_CUSTOM_TEMPLATES = Object.freeze({
|
|
376 |
// to be repeated twice. We replicate this behaviour here.
|
377 |
target: `You are a friendly chatbot who always responds in the style of a pirateYou are a friendly chatbot who always responds in the style of a pirate### Instruction: Hello, how are you?### Response: I'm doing great. How can I help you today?### Instruction: I'd like to show off how chat templating works!`,
|
378 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
379 |
});
|
380 |
|
381 |
describe("End-to-end tests", () => {
|
|
|
376 |
// to be repeated twice. We replicate this behaviour here.
|
377 |
target: `You are a friendly chatbot who always responds in the style of a pirateYou are a friendly chatbot who always responds in the style of a pirate### Instruction: Hello, how are you?### Response: I'm doing great. How can I help you today?### Instruction: I'd like to show off how chat templating works!`,
|
378 |
},
|
379 |
+
"CohereForAI/c4ai-command-r-v01": {
|
380 |
+
chat_template:
|
381 |
+
`{{ bos_token }}{% if messages[0]['role'] == 'system' %}{% set loop_messages = messages[1:] %}{% set system_message = messages[0]['content'] %}{% else %}{% set loop_messages = messages %}{% set system_message = '## Task and Context\\nYou help people answer their questions and other requests interactively. You will be asked a very wide array of requests on all kinds of topics. You will be equipped with a wide range of search engines or similar tools to help you, which you use to research your answer. You should focus on serving the user\\'s needs as best you can, which will be wide-ranging.\\n\\n## Style Guide\\nUnless the user asks for a different style of answer, you should answer in full sentences, using proper grammar and spelling.' %}{% endif %}` +
|
382 |
+
`{{ '<|START_OF_TURN_TOKEN|><|SYSTEM_TOKEN|>' }}{{ '# Safety Preamble' }}{{ '\nThe instructions in this section override those in the task description and style guide sections. Don\\'t answer questions that are harmful or immoral.' }}{{ '\n\n# System Preamble' }}{{ '\n## Basic Rules' }}{{ '\nYou are a powerful conversational AI trained by Cohere to help people. You are augmented by a number of tools, and your job is to use and consume the output of these tools to best help the user. You will see a conversation history between yourself and a user, ending with an utterance from the user. You will then see a specific instruction instructing you what kind of response to generate. When you answer the user\\'s requests, you cite your sources in your answers, according to those instructions.' }}` +
|
383 |
+
`{{ '\n\n# User Preamble' }}{{ '\n' + system_message }}` +
|
384 |
+
`{{'\n\n## Available Tools\nHere is a list of tools that you have available to you:\n\n'}}{% for tool in tools %}{% if loop.index0 != 0 %}{{ '\n\n'}}{% endif %}{{'\`\`\`python\ndef ' + tool.name + '('}}{% for param_name, param_fields in tool.parameter_definitions.items() %}{% if loop.index0 != 0 %}{{ ', '}}{% endif %}{{param_name}}: {% if not param_fields.required %}{{'Optional[' + param_fields.type + '] = None'}}{% else %}{{ param_fields.type }}{% endif %}{% endfor %}{{ ') -> List[Dict]:\n """'}}{{ tool.description }}{% if tool.parameter_definitions|length != 0 %}{{ '\n\n Args:\n '}}{% for param_name, param_fields in tool.parameter_definitions.items() %}{% if loop.index0 != 0 %}{{ '\n ' }}{% endif %}{{ param_name + ' ('}}{% if not param_fields.required %}{{'Optional[' + param_fields.type + ']'}}{% else %}{{ param_fields.type }}{% endif %}{{ '): ' + param_fields.description }}{% endfor %}{% endif %}{{ '\n """\n pass\n\`\`\`' }}{% endfor %}{{ '<|END_OF_TURN_TOKEN|>'}}` +
|
385 |
+
`{% for message in loop_messages %}{% set content = message['content'] %}{% if message['role'] == 'user' %}{{ '<|START_OF_TURN_TOKEN|><|USER_TOKEN|>' + content.strip() + '<|END_OF_TURN_TOKEN|>' }}{% elif message['role'] == 'system' %}{{ '<|START_OF_TURN_TOKEN|><|SYSTEM_TOKEN|>' + content.strip() + '<|END_OF_TURN_TOKEN|>' }}{% elif message['role'] == 'assistant' %}{{ '<|START_OF_TURN_TOKEN|><|CHATBOT_TOKEN|>' + content.strip() + '<|END_OF_TURN_TOKEN|>' }}{% endif %}{% endfor %}` +
|
386 |
+
`{{'<|START_OF_TURN_TOKEN|><|SYSTEM_TOKEN|>Write \\'Action:\\' followed by a json-formatted list of actions that you want to perform in order to produce a good response to the user\\'s last input. You can use any of the supplied tools any number of times, but you should aim to execute the minimum number of necessary actions for the input. You should use the \`directly-answer\` tool if calling the other tools is unnecessary. The list of actions you want to call should be formatted as a list of json objects, for example:\n\`\`\`json\n[\n {\n "tool_name": title of the tool in the specification,\n "parameters": a dict of parameters to input into the tool as they are defined in the specs, or {} if it takes no parameters\n }\n]\`\`\`<|END_OF_TURN_TOKEN|>'}}{% if add_generation_prompt %}{{ '<|START_OF_TURN_TOKEN|><|CHATBOT_TOKEN|>' }}{% endif %}`,
|
387 |
+
|
388 |
+
data: {
|
389 |
+
messages: [{ role: "user", content: "Whats the biggest penguin in the world?" }],
|
390 |
+
tools: [
|
391 |
+
{
|
392 |
+
name: "internet_search",
|
393 |
+
description: "Returns a list of relevant document snippets for a textual query retrieved from the internet",
|
394 |
+
parameter_definitions: {
|
395 |
+
query: {
|
396 |
+
description: "Query to search the internet with",
|
397 |
+
type: "str",
|
398 |
+
required: true,
|
399 |
+
},
|
400 |
+
},
|
401 |
+
},
|
402 |
+
{
|
403 |
+
name: "directly_answer",
|
404 |
+
description:
|
405 |
+
"Calls a standard (un-augmented) AI chatbot to generate a response given the conversation history",
|
406 |
+
parameter_definitions: {},
|
407 |
+
},
|
408 |
+
],
|
409 |
+
bos_token: "<BOS_TOKEN>",
|
410 |
+
add_generation_prompt: true,
|
411 |
+
},
|
412 |
+
target:
|
413 |
+
"<BOS_TOKEN><|START_OF_TURN_TOKEN|><|SYSTEM_TOKEN|># Safety Preamble\nThe instructions in this section override those in the task description and style guide sections. Don't answer questions that are harmful or immoral.\n\n# System Preamble\n## Basic Rules\nYou are a powerful conversational AI trained by Cohere to help people. You are augmented by a number of tools, and your job is to use and consume the output of these tools to best help the user. You will see a conversation history between yourself and a user, ending with an utterance from the user. You will then see a specific instruction instructing you what kind of response to generate. When you answer the user's requests, you cite your sources in your answers, according to those instructions." +
|
414 |
+
"\n\n# User Preamble\n## Task and Context\nYou help people answer their questions and other requests interactively. You will be asked a very wide array of requests on all kinds of topics. You will be equipped with a wide range of search engines or similar tools to help you, which you use to research your answer. You should focus on serving the user's needs as best you can, which will be wide-ranging.\n\n## Style Guide\nUnless the user asks for a different style of answer, you should answer in full sentences, using proper grammar and spelling." +
|
415 |
+
'\n\n## Available Tools\nHere is a list of tools that you have available to you:\n\n```python\ndef internet_search(query: str) -> List[Dict]:\n """Returns a list of relevant document snippets for a textual query retrieved from the internet\n\n Args:\n query (str): Query to search the internet with\n """\n pass\n```\n\n```python\ndef directly_answer() -> List[Dict]:\n """Calls a standard (un-augmented) AI chatbot to generate a response given the conversation history\n """\n pass\n```<|END_OF_TURN_TOKEN|>' +
|
416 |
+
"<|START_OF_TURN_TOKEN|><|USER_TOKEN|>Whats the biggest penguin in the world?<|END_OF_TURN_TOKEN|>" +
|
417 |
+
'<|START_OF_TURN_TOKEN|><|SYSTEM_TOKEN|>Write \'Action:\' followed by a json-formatted list of actions that you want to perform in order to produce a good response to the user\'s last input. You can use any of the supplied tools any number of times, but you should aim to execute the minimum number of necessary actions for the input. You should use the `directly-answer` tool if calling the other tools is unnecessary. The list of actions you want to call should be formatted as a list of json objects, for example:\n```json\n[\n {\n "tool_name": title of the tool in the specification,\n "parameters": a dict of parameters to input into the tool as they are defined in the specs, or {} if it takes no parameters\n }\n]```<|END_OF_TURN_TOKEN|><|START_OF_TURN_TOKEN|><|CHATBOT_TOKEN|>',
|
418 |
+
},
|
419 |
});
|
420 |
|
421 |
describe("End-to-end tests", () => {
|
packages/jinja/test/templates.test.js
CHANGED
@@ -27,6 +27,7 @@ const TEST_STRINGS = {
|
|
27 |
|
28 |
// For loops
|
29 |
FOR_LOOP: `{% for message in messages %}{{ message['content'] }}{% endfor %}`,
|
|
|
30 |
|
31 |
// Set variables
|
32 |
VARIABLES: `{% set x = 'Hello' %}{% set y = 'World' %}{{ x + ' ' + y }}`,
|
@@ -76,6 +77,7 @@ const TEST_STRINGS = {
|
|
76 |
FILTER_OPERATOR_3: `|{{ -1 | abs }}|{{ 1 | abs }}|`,
|
77 |
FILTER_OPERATOR_4: `{{ items | selectattr('key') | length }}`,
|
78 |
FILTER_OPERATOR_5: `{{ messages | selectattr('role', 'equalto', 'system') | length }}`,
|
|
|
79 |
|
80 |
// Logical operators between non-Booleans
|
81 |
BOOLEAN_NUMERICAL: `|{{ 1 and 2 }}|{{ 1 and 0 }}|{{ 0 and 1 }}|{{ 0 and 0 }}|{{ 1 or 2 }}|{{ 1 or 0 }}|{{ 0 or 1 }}|{{ 0 or 0 }}|{{ not 1 }}|{{ not 0 }}|`,
|
@@ -103,6 +105,7 @@ const TEST_STRINGS = {
|
|
103 |
// Object operators
|
104 |
OBJECT_OPERATORS: `|{{ 'known' in obj }}|{{ 'known' not in obj }}|{{ 'unknown' in obj }}|{{ 'unknown' not in obj }}|`,
|
105 |
OBJECT_OPERATORS_1: `|{{ obj.get('known') }}|{{ obj.get('unknown') is none }}|{{ obj.get('unknown') is defined }}|`,
|
|
|
106 |
|
107 |
// Scope
|
108 |
SCOPE: `{% set ns = namespace(found=false) %}{% for num in nums %}{% if num == 1 %}{{ 'found=' }}{% set ns.found = true %}{% endif %}{% endfor %}{{ ns.found }}`,
|
@@ -118,6 +121,9 @@ const TEST_STRINGS = {
|
|
118 |
// Array literals
|
119 |
ARRAY_LITERALS: `{{ [1, true, 'hello', [1, 2, 3, 4], var] | length }}`,
|
120 |
|
|
|
|
|
|
|
121 |
// Object literals
|
122 |
OBJECT_LITERALS: `{{ { 'key': 'value', key: 'value2', "key3": [1, {'foo': 'bar'} ] }['key'] }}`,
|
123 |
|
@@ -520,6 +526,42 @@ const TEST_PARSED = {
|
|
520 |
{ value: "endfor", type: "EndFor" },
|
521 |
{ value: "%}", type: "CloseStatement" },
|
522 |
],
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
523 |
|
524 |
// Set variables
|
525 |
VARIABLES: [
|
@@ -1343,6 +1385,29 @@ const TEST_PARSED = {
|
|
1343 |
{ value: "length", type: "Identifier" },
|
1344 |
{ value: "}}", type: "CloseExpression" },
|
1345 |
],
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1346 |
|
1347 |
// Logical operators between non-Booleans
|
1348 |
BOOLEAN_NUMERICAL: [
|
@@ -1952,6 +2017,34 @@ const TEST_PARSED = {
|
|
1952 |
{ value: "}}", type: "CloseExpression" },
|
1953 |
{ value: "|", type: "Text" },
|
1954 |
],
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1955 |
|
1956 |
// Scope
|
1957 |
SCOPE: [
|
@@ -2132,6 +2225,23 @@ const TEST_PARSED = {
|
|
2132 |
{ value: "}}", type: "CloseExpression" },
|
2133 |
],
|
2134 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2135 |
// Object literals
|
2136 |
OBJECT_LITERALS: [
|
2137 |
{ value: "{{", type: "OpenExpression" },
|
@@ -2217,6 +2327,7 @@ const TEST_CONTEXT = {
|
|
2217 |
{ role: "user", content: "C" },
|
2218 |
],
|
2219 |
},
|
|
|
2220 |
|
2221 |
// Set variables
|
2222 |
VARIABLES: {},
|
@@ -2304,6 +2415,9 @@ const TEST_CONTEXT = {
|
|
2304 |
FILTER_OPERATOR_5: {
|
2305 |
messages: [{ role: "system" }, { role: "user" }, { role: "assistant" }],
|
2306 |
},
|
|
|
|
|
|
|
2307 |
|
2308 |
// Logical operators between non-Booleans
|
2309 |
BOOLEAN_NUMERICAL: {},
|
@@ -2343,6 +2457,9 @@ const TEST_CONTEXT = {
|
|
2343 |
known: true,
|
2344 |
},
|
2345 |
},
|
|
|
|
|
|
|
2346 |
|
2347 |
// Scope
|
2348 |
SCOPE: { nums: [1, 2, 3] },
|
@@ -2358,6 +2475,9 @@ const TEST_CONTEXT = {
|
|
2358 |
// Array literals
|
2359 |
ARRAY_LITERALS: { var: true },
|
2360 |
|
|
|
|
|
|
|
2361 |
// Object literals
|
2362 |
OBJECT_LITERALS: {
|
2363 |
key: "key2",
|
@@ -2390,6 +2510,7 @@ const EXPECTED_OUTPUTS = {
|
|
2390 |
|
2391 |
// For loops
|
2392 |
FOR_LOOP: "ABC",
|
|
|
2393 |
|
2394 |
// Set variables
|
2395 |
VARIABLES: "Hello World",
|
@@ -2439,6 +2560,7 @@ const EXPECTED_OUTPUTS = {
|
|
2439 |
FILTER_OPERATOR_3: `|1|1|`,
|
2440 |
FILTER_OPERATOR_4: `2`,
|
2441 |
FILTER_OPERATOR_5: `1`,
|
|
|
2442 |
|
2443 |
// Logical operators between non-Booleans
|
2444 |
BOOLEAN_NUMERICAL: `|2|0|0|0|1|1|1|0|false|true|`,
|
@@ -2466,6 +2588,7 @@ const EXPECTED_OUTPUTS = {
|
|
2466 |
// Object operators
|
2467 |
OBJECT_OPERATORS: `|true|false|false|true|`,
|
2468 |
OBJECT_OPERATORS_1: `|true|true|true|`,
|
|
|
2469 |
|
2470 |
// Scope
|
2471 |
SCOPE: `found=true`,
|
@@ -2481,6 +2604,9 @@ const EXPECTED_OUTPUTS = {
|
|
2481 |
// Array literals
|
2482 |
ARRAY_LITERALS: `5`,
|
2483 |
|
|
|
|
|
|
|
2484 |
// Object literals
|
2485 |
OBJECT_LITERALS: `value`,
|
2486 |
|
|
|
27 |
|
28 |
// For loops
|
29 |
FOR_LOOP: `{% for message in messages %}{{ message['content'] }}{% endfor %}`,
|
30 |
+
FOR_LOOP_UNPACKING: `|{% for x, y in [ [1, 2], [3, 4] ] %}|{{ x + ' ' + y }}|{% endfor %}|`,
|
31 |
|
32 |
// Set variables
|
33 |
VARIABLES: `{% set x = 'Hello' %}{% set y = 'World' %}{{ x + ' ' + y }}`,
|
|
|
77 |
FILTER_OPERATOR_3: `|{{ -1 | abs }}|{{ 1 | abs }}|`,
|
78 |
FILTER_OPERATOR_4: `{{ items | selectattr('key') | length }}`,
|
79 |
FILTER_OPERATOR_5: `{{ messages | selectattr('role', 'equalto', 'system') | length }}`,
|
80 |
+
FILTER_OPERATOR_6: `|{{ obj | length }}|{{ (obj | items)[1:] | length }}|`,
|
81 |
|
82 |
// Logical operators between non-Booleans
|
83 |
BOOLEAN_NUMERICAL: `|{{ 1 and 2 }}|{{ 1 and 0 }}|{{ 0 and 1 }}|{{ 0 and 0 }}|{{ 1 or 2 }}|{{ 1 or 0 }}|{{ 0 or 1 }}|{{ 0 or 0 }}|{{ not 1 }}|{{ not 0 }}|`,
|
|
|
105 |
// Object operators
|
106 |
OBJECT_OPERATORS: `|{{ 'known' in obj }}|{{ 'known' not in obj }}|{{ 'unknown' in obj }}|{{ 'unknown' not in obj }}|`,
|
107 |
OBJECT_OPERATORS_1: `|{{ obj.get('known') }}|{{ obj.get('unknown') is none }}|{{ obj.get('unknown') is defined }}|`,
|
108 |
+
OBJECT_OPERATORS_2: `|{% for x, y in obj.items() %}|{{ x + ' ' + y }}|{% endfor %}|`,
|
109 |
|
110 |
// Scope
|
111 |
SCOPE: `{% set ns = namespace(found=false) %}{% for num in nums %}{% if num == 1 %}{{ 'found=' }}{% set ns.found = true %}{% endif %}{% endfor %}{{ ns.found }}`,
|
|
|
121 |
// Array literals
|
122 |
ARRAY_LITERALS: `{{ [1, true, 'hello', [1, 2, 3, 4], var] | length }}`,
|
123 |
|
124 |
+
// Tuple literals
|
125 |
+
TUPLE_LITERALS: `{{ (1, (1, 2)) | length }}`,
|
126 |
+
|
127 |
// Object literals
|
128 |
OBJECT_LITERALS: `{{ { 'key': 'value', key: 'value2', "key3": [1, {'foo': 'bar'} ] }['key'] }}`,
|
129 |
|
|
|
526 |
{ value: "endfor", type: "EndFor" },
|
527 |
{ value: "%}", type: "CloseStatement" },
|
528 |
],
|
529 |
+
FOR_LOOP_UNPACKING: [
|
530 |
+
{ value: "|", type: "Text" },
|
531 |
+
{ value: "{%", type: "OpenStatement" },
|
532 |
+
{ value: "for", type: "For" },
|
533 |
+
{ value: "x", type: "Identifier" },
|
534 |
+
{ value: ",", type: "Comma" },
|
535 |
+
{ value: "y", type: "Identifier" },
|
536 |
+
{ value: "in", type: "In" },
|
537 |
+
{ value: "[", type: "OpenSquareBracket" },
|
538 |
+
{ value: "[", type: "OpenSquareBracket" },
|
539 |
+
{ value: "1", type: "NumericLiteral" },
|
540 |
+
{ value: ",", type: "Comma" },
|
541 |
+
{ value: "2", type: "NumericLiteral" },
|
542 |
+
{ value: "]", type: "CloseSquareBracket" },
|
543 |
+
{ value: ",", type: "Comma" },
|
544 |
+
{ value: "[", type: "OpenSquareBracket" },
|
545 |
+
{ value: "3", type: "NumericLiteral" },
|
546 |
+
{ value: ",", type: "Comma" },
|
547 |
+
{ value: "4", type: "NumericLiteral" },
|
548 |
+
{ value: "]", type: "CloseSquareBracket" },
|
549 |
+
{ value: "]", type: "CloseSquareBracket" },
|
550 |
+
{ value: "%}", type: "CloseStatement" },
|
551 |
+
{ value: "|", type: "Text" },
|
552 |
+
{ value: "{{", type: "OpenExpression" },
|
553 |
+
{ value: "x", type: "Identifier" },
|
554 |
+
{ value: "+", type: "AdditiveBinaryOperator" },
|
555 |
+
{ value: " ", type: "StringLiteral" },
|
556 |
+
{ value: "+", type: "AdditiveBinaryOperator" },
|
557 |
+
{ value: "y", type: "Identifier" },
|
558 |
+
{ value: "}}", type: "CloseExpression" },
|
559 |
+
{ value: "|", type: "Text" },
|
560 |
+
{ value: "{%", type: "OpenStatement" },
|
561 |
+
{ value: "endfor", type: "EndFor" },
|
562 |
+
{ value: "%}", type: "CloseStatement" },
|
563 |
+
{ value: "|", type: "Text" },
|
564 |
+
],
|
565 |
|
566 |
// Set variables
|
567 |
VARIABLES: [
|
|
|
1385 |
{ value: "length", type: "Identifier" },
|
1386 |
{ value: "}}", type: "CloseExpression" },
|
1387 |
],
|
1388 |
+
FILTER_OPERATOR_6: [
|
1389 |
+
{ value: "|", type: "Text" },
|
1390 |
+
{ value: "{{", type: "OpenExpression" },
|
1391 |
+
{ value: "obj", type: "Identifier" },
|
1392 |
+
{ value: "|", type: "Pipe" },
|
1393 |
+
{ value: "length", type: "Identifier" },
|
1394 |
+
{ value: "}}", type: "CloseExpression" },
|
1395 |
+
{ value: "|", type: "Text" },
|
1396 |
+
{ value: "{{", type: "OpenExpression" },
|
1397 |
+
{ value: "(", type: "OpenParen" },
|
1398 |
+
{ value: "obj", type: "Identifier" },
|
1399 |
+
{ value: "|", type: "Pipe" },
|
1400 |
+
{ value: "items", type: "Identifier" },
|
1401 |
+
{ value: ")", type: "CloseParen" },
|
1402 |
+
{ value: "[", type: "OpenSquareBracket" },
|
1403 |
+
{ value: "1", type: "NumericLiteral" },
|
1404 |
+
{ value: ":", type: "Colon" },
|
1405 |
+
{ value: "]", type: "CloseSquareBracket" },
|
1406 |
+
{ value: "|", type: "Pipe" },
|
1407 |
+
{ value: "length", type: "Identifier" },
|
1408 |
+
{ value: "}}", type: "CloseExpression" },
|
1409 |
+
{ value: "|", type: "Text" },
|
1410 |
+
],
|
1411 |
|
1412 |
// Logical operators between non-Booleans
|
1413 |
BOOLEAN_NUMERICAL: [
|
|
|
2017 |
{ value: "}}", type: "CloseExpression" },
|
2018 |
{ value: "|", type: "Text" },
|
2019 |
],
|
2020 |
+
OBJECT_OPERATORS_2: [
|
2021 |
+
{ value: "|", type: "Text" },
|
2022 |
+
{ value: "{%", type: "OpenStatement" },
|
2023 |
+
{ value: "for", type: "For" },
|
2024 |
+
{ value: "x", type: "Identifier" },
|
2025 |
+
{ value: ",", type: "Comma" },
|
2026 |
+
{ value: "y", type: "Identifier" },
|
2027 |
+
{ value: "in", type: "In" },
|
2028 |
+
{ value: "obj", type: "Identifier" },
|
2029 |
+
{ value: ".", type: "Dot" },
|
2030 |
+
{ value: "items", type: "Identifier" },
|
2031 |
+
{ value: "(", type: "OpenParen" },
|
2032 |
+
{ value: ")", type: "CloseParen" },
|
2033 |
+
{ value: "%}", type: "CloseStatement" },
|
2034 |
+
{ value: "|", type: "Text" },
|
2035 |
+
{ value: "{{", type: "OpenExpression" },
|
2036 |
+
{ value: "x", type: "Identifier" },
|
2037 |
+
{ value: "+", type: "AdditiveBinaryOperator" },
|
2038 |
+
{ value: " ", type: "StringLiteral" },
|
2039 |
+
{ value: "+", type: "AdditiveBinaryOperator" },
|
2040 |
+
{ value: "y", type: "Identifier" },
|
2041 |
+
{ value: "}}", type: "CloseExpression" },
|
2042 |
+
{ value: "|", type: "Text" },
|
2043 |
+
{ value: "{%", type: "OpenStatement" },
|
2044 |
+
{ value: "endfor", type: "EndFor" },
|
2045 |
+
{ value: "%}", type: "CloseStatement" },
|
2046 |
+
{ value: "|", type: "Text" },
|
2047 |
+
],
|
2048 |
|
2049 |
// Scope
|
2050 |
SCOPE: [
|
|
|
2225 |
{ value: "}}", type: "CloseExpression" },
|
2226 |
],
|
2227 |
|
2228 |
+
// Tuple literals
|
2229 |
+
TUPLE_LITERALS: [
|
2230 |
+
{ value: "{{", type: "OpenExpression" },
|
2231 |
+
{ value: "(", type: "OpenParen" },
|
2232 |
+
{ value: "1", type: "NumericLiteral" },
|
2233 |
+
{ value: ",", type: "Comma" },
|
2234 |
+
{ value: "(", type: "OpenParen" },
|
2235 |
+
{ value: "1", type: "NumericLiteral" },
|
2236 |
+
{ value: ",", type: "Comma" },
|
2237 |
+
{ value: "2", type: "NumericLiteral" },
|
2238 |
+
{ value: ")", type: "CloseParen" },
|
2239 |
+
{ value: ")", type: "CloseParen" },
|
2240 |
+
{ value: "|", type: "Pipe" },
|
2241 |
+
{ value: "length", type: "Identifier" },
|
2242 |
+
{ value: "}}", type: "CloseExpression" },
|
2243 |
+
],
|
2244 |
+
|
2245 |
// Object literals
|
2246 |
OBJECT_LITERALS: [
|
2247 |
{ value: "{{", type: "OpenExpression" },
|
|
|
2327 |
{ role: "user", content: "C" },
|
2328 |
],
|
2329 |
},
|
2330 |
+
FOR_LOOP_UNPACKING: {},
|
2331 |
|
2332 |
// Set variables
|
2333 |
VARIABLES: {},
|
|
|
2415 |
FILTER_OPERATOR_5: {
|
2416 |
messages: [{ role: "system" }, { role: "user" }, { role: "assistant" }],
|
2417 |
},
|
2418 |
+
FILTER_OPERATOR_6: {
|
2419 |
+
obj: { a: 1, b: 2, c: 3 },
|
2420 |
+
},
|
2421 |
|
2422 |
// Logical operators between non-Booleans
|
2423 |
BOOLEAN_NUMERICAL: {},
|
|
|
2457 |
known: true,
|
2458 |
},
|
2459 |
},
|
2460 |
+
OBJECT_OPERATORS_2: {
|
2461 |
+
obj: { a: 1, b: 2, c: 3 },
|
2462 |
+
},
|
2463 |
|
2464 |
// Scope
|
2465 |
SCOPE: { nums: [1, 2, 3] },
|
|
|
2475 |
// Array literals
|
2476 |
ARRAY_LITERALS: { var: true },
|
2477 |
|
2478 |
+
// Tuple literals
|
2479 |
+
TUPLE_LITERALS: {},
|
2480 |
+
|
2481 |
// Object literals
|
2482 |
OBJECT_LITERALS: {
|
2483 |
key: "key2",
|
|
|
2510 |
|
2511 |
// For loops
|
2512 |
FOR_LOOP: "ABC",
|
2513 |
+
FOR_LOOP_UNPACKING: "||1 2||3 4||",
|
2514 |
|
2515 |
// Set variables
|
2516 |
VARIABLES: "Hello World",
|
|
|
2560 |
FILTER_OPERATOR_3: `|1|1|`,
|
2561 |
FILTER_OPERATOR_4: `2`,
|
2562 |
FILTER_OPERATOR_5: `1`,
|
2563 |
+
FILTER_OPERATOR_6: `|3|2|`,
|
2564 |
|
2565 |
// Logical operators between non-Booleans
|
2566 |
BOOLEAN_NUMERICAL: `|2|0|0|0|1|1|1|0|false|true|`,
|
|
|
2588 |
// Object operators
|
2589 |
OBJECT_OPERATORS: `|true|false|false|true|`,
|
2590 |
OBJECT_OPERATORS_1: `|true|true|true|`,
|
2591 |
+
OBJECT_OPERATORS_2: `||a 1||b 2||c 3||`,
|
2592 |
|
2593 |
// Scope
|
2594 |
SCOPE: `found=true`,
|
|
|
2604 |
// Array literals
|
2605 |
ARRAY_LITERALS: `5`,
|
2606 |
|
2607 |
+
// Tuple literals
|
2608 |
+
TUPLE_LITERALS: `2`,
|
2609 |
+
|
2610 |
// Object literals
|
2611 |
OBJECT_LITERALS: `value`,
|
2612 |
|
packages/tasks/src/model-libraries.ts
CHANGED
@@ -202,11 +202,11 @@ export const MODEL_LIBRARIES_UI_ELEMENTS = {
|
|
202 |
snippets: snippets.mlx,
|
203 |
filter: true,
|
204 |
},
|
205 |
-
|
206 |
-
prettyLabel: "
|
207 |
repoName: "mlx-image",
|
208 |
repoUrl: "https://github.com/riccardomusmeci/mlx-image",
|
209 |
-
docsUrl: "https://huggingface.co/docs/hub/
|
210 |
snippets: snippets.mlxim,
|
211 |
filter: false,
|
212 |
countDownloads: { term: { path: "model.safetensors" } },
|
|
|
202 |
snippets: snippets.mlx,
|
203 |
filter: true,
|
204 |
},
|
205 |
+
"mlx-image": {
|
206 |
+
prettyLabel: "mlx-image",
|
207 |
repoName: "mlx-image",
|
208 |
repoUrl: "https://github.com/riccardomusmeci/mlx-image",
|
209 |
+
docsUrl: "https://huggingface.co/docs/hub/mlx-image",
|
210 |
snippets: snippets.mlxim,
|
211 |
filter: false,
|
212 |
countDownloads: { term: { path: "model.safetensors" } },
|