Skip to content

Commit 59a59bd

Browse files
authored
Merge pull request #1 from Tanuki/support/togetherai
[WIP] Support/togetherai
2 parents f47b23f + 0e5628c commit 59a59bd

File tree

85 files changed

+4285
-24188
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

85 files changed

+4285
-24188
lines changed

.env

Lines changed: 0 additions & 4 deletions
This file was deleted.

.eslintrc.yml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
root: true
2+
parser: "@typescript-eslint/parser"
3+
plugins:
4+
- "@typescript-eslint"
5+
- "node"
6+
- "prettier"
7+
parserOptions:
8+
project:
9+
- "./tsconfig.json"
10+
extends:
11+
- "eslint:recommended"
12+
- "plugin:node/recommended"
13+
- "plugin:@typescript-eslint/eslint-recommended"
14+
- "plugin:@typescript-eslint/recommended"
15+
- "plugin:@typescript-eslint/recommended-requiring-type-checking"
16+
- "plugin:prettier/recommended"
17+
rules:
18+
prettier/prettier: "warn"
19+
node/no-missing-import: "off"
20+
node/no-empty-function: "off"
21+
node/no-unsupported-features/es-syntax: "off"
22+
node/no-missing-require: "off"
23+
node/shebang: "off"
24+
"@typescript-eslint/no-use-before-define": "off"
25+
quotes:
26+
- "warn"
27+
- "single"
28+
- avoidEscape: true
29+
node/no-unpublished-import: "off"
30+
"@typescript-eslint/no-unsafe-assignment": "off"
31+
"@typescript-eslint/no-var-requires": "off"
32+
"@typescript-eslint/ban-ts-comment": "off"
33+
"@typescript-eslint/no-explicit-any": "off"

.github/workflows/pr.yml

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,27 @@
1-
# Reusable workflow for PRs; to eject, you can replace this file with
2-
# https://github.com/ryansonshine/ryansonshine/blob/main/.github/workflows/pr.yml
31
name: Pull Request
42

5-
on: [pull_request]
3+
on:
4+
workflow_call:
65

76
jobs:
87
build:
9-
uses: ryansonshine/ryansonshine/.github/workflows/pr.yml@main
8+
runs-on: ubuntu-latest
9+
10+
strategy:
11+
matrix:
12+
node-version: [16.x, 18.x]
13+
14+
steps:
15+
- uses: actions/checkout@v3
16+
- name: Use Node.js ${{ matrix.node-version }}
17+
uses: actions/setup-node@v3
18+
with:
19+
node-version: ${{ matrix.node-version }}
20+
- run: npm ci
21+
- run: npm run build --if-present
22+
- run: npm test --coverage
23+
- name: Upload Code Coverage
24+
uses: codecov/codecov-action@v3.1.0
25+
with:
26+
token: ${{ secrets.CODECOV_TOKEN }} # Not needed for public repos
27+
directory: ./coverage

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,3 +117,6 @@ dist
117117

118118
# Compiled code
119119
lib/
120+
/.env
121+
.env
122+
tests/testModelProviders/.env

.eslintrc.js renamed to .old.eslintrc.mjs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ export default {
44
plugins: ['@typescript-eslint', 'node', 'prettier'],
55
parserOptions: {
66
tsconfigRootDir: __dirname,
7-
project: ['./tsconfig.json'],
7+
project: './tsconfig.json',
8+
ecmaVersion: 2020,
9+
sourceType: 'module'
810
},
911
extends: [
1012
'eslint:recommended',

README.md

Lines changed: 44 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
# Tanuki <span style="font-family:Papyrus; font-size:2em;">🦝</span> ![Discord](https://img.shields.io/discord/1168948553222197248)
2-
Easily build LLM-powered apps that get cheaper and faster over time.
1+
# Tanuki <span style="font-family:Papyrus; font-size:2em;">🦝</span> ![Discord](https://img.shields.io/discord/1168948553222197248) [![codecov](https://codecov.io/gh/Tanuki/tanuki.ts/branch/main/graph/badge.svg?token=b169ecba-fa1c-43ee-a9e0-18597d2aaffa)](https://codecov.io/gh/Tanuki/tanuki.ts)
2+
3+
Build LLM-powered apps that get cheaper and faster over time.
34

45
---
56

@@ -40,17 +41,19 @@ Lastly, the more you use Tanuki functions, the cheaper and faster they gets (up
4041
* Declare the function that you want Tanuki to provide.
4142
*/
4243
class Functions {
43-
someFunction = patch<TypedOutput, TypedInput>()`Include the instruction that your function will execute`;
44+
static someFunction = patch<TypedOutput, TypedInput>()
45+
`{The instruction that your function will execute}`;
4446
}
4547

4648
/**
4749
* Align your function to the expected behaviour using Jest-like assertions
4850
*/
4951
Tanuki.align(async (it) => {
50-
it("testSomeFunction", async (expect) => {
52+
it("should correctly classify positive affirmation", async (expect) => {
5153
const exampleTypedInput: TypedInput = "I love you";
5254
const exampleTypedOutput: TypedOutput = "Good";
53-
expect(await new Functions().someFunction(exampleTypedInput)).toEqual(exampleTypedOutput);
55+
const result = await Functions.someFunction(exampleTypedInput);
56+
expect(result).toEqual(exampleTypedOutput);
5457
});
5558
});
5659
```
@@ -68,6 +71,7 @@ Tanuki.align(async (it) => {
6871
<!-- TOC --><a name="installation-and-getting-started"></a>
6972
## Installation and Getting Started
7073
<!-- TOC --><a name="installation"></a>
74+
7175
### Installation
7276
```bash
7377
npm install tanuki.ts
@@ -84,7 +88,8 @@ export AWS_SECRET_ACCESS_KEY=...
8488
export AWS_ACCESS_KEY_ID=...
8589
```
8690

87-
Next, we need to install the Tanuki type transformer. This will allow Tanuki to be aware of your patched functions and types at runtime, as these types are usually erased by the Typescript compiler when transpiling into Javascript.
91+
#### Default Setup
92+
Next, we need to install the Tanuki type transformer. This will allow Tanuki to be aware of your patched functions and types at runtime, as these types are erased when transpiling into Javascript.
8893
```typescript
8994
npm install ts-patch --save-dev
9095
npx ts-patch install
@@ -103,15 +108,28 @@ Next, you need to add the Tanuki transformer to your `tsconfig.json` file:
103108
}
104109
}
105110
```
106-
This is required for Tanuki to be aware of your patched functions and types at runtime, as these types are usually erased by the Typescript compiler when transpiling into Javascript.
107111

112+
#### Next.js Setup
113+
As Next.js has it's own build system, you must explicitly add the Tanuki transformer to your `package.json` file instead by adding the following scripts.
114+
115+
```json
116+
{
117+
"scripts": {
118+
"predev": "tanuki-type-compiler",
119+
"prebuild": "tanuki-type-compiler",
120+
"prestart": "tanuki-type-compiler"
121+
}
122+
}
123+
```
124+
125+
This will ensure that Tanuki can extract your patched functions before the Next.js build process.
108126

109127

110128
<!-- TOC --><a name="getting-started"></a>
111129
### Getting Started
112130

113131
To get started:
114-
1. Create a `patch` function stub, including your input and output types, and an instruction.
132+
1. Create a `patch` function stub as a static member of a class, including your input and output types, and an instruction.
115133
2. (Optional) Create jest-like equivalent assertions in a `Tanuki.align` block, declaring the expected behaviour of your patched function with different inputs.
116134

117135
Once you have built your code (to make Tanuki aware of your types), the `patch` function will be registered and can be invoked as normal.
@@ -133,26 +151,25 @@ type Message = string;
133151
* Declare the function that you want Tanuki to provide.
134152
*/
135153
class Functions {
136-
classifySentiment = patch<Sentiment, Message>()`Classifies message from the user based on sentiment`;
154+
static classifySentiment = patch<Sentiment, Message>()
155+
`Classifies message from the user based on sentiment`;
137156
}
138157

139158
/**
140159
* Align your function to the expected behavior using Jest-like assertions.
141160
*/
142161
Tanuki.align(async (it) => {
143162
it("alignClassifySentiment", async (expect) => {
144-
const functions = new Functions();
145-
expect(await functions.classifySentiment("I love you")).toEqual('Good');
146-
expect(await functions.classifySentiment("I hate you")).toEqual('Bad');
147-
expect(await functions.classifySentiment("People from Phoenix are called Phoenicians")).toBeNull();
163+
expect(await Functions.classifySentiment("I love you")).toEqual('Good');
164+
expect(await Functions.classifySentiment("I hate you")).toEqual('Bad');
165+
expect(await Functions.classifySentiment("People from Phoenix are called Phoenicians")).toBeNull();
148166
});
149167
});
150168

151169
// Example usage of the patched function somewhere else in your code
152170
const runExamples = async () => {
153-
const functions = new Functions();
154-
console.log(await functions.classifySentiment("I like you")); // Expect 'Good' or null
155-
console.log(await functions.classifySentiment("Apples might be red")); // Expect null
171+
console.log(await Functions.classifySentiment("I like you")); // Expect 'Good' or null
172+
console.log(await Functions.classifySentiment("Apples might be red")); // Expect null
156173
};
157174

158175
runExamples();
@@ -264,15 +281,16 @@ Test-Driven Alignment (TDA) adapts this concept to align the behavior of a patch
264281

265282
To align the behaviour of your patched function to your needs, decorate a function with `@align` and assert the outputs of the function with the ‘assert’ statement as is done with standard tests.
266283

267-
```python
268-
@tanuki.align
269-
def align_classify_sentiment():
270-
assert classify_sentiment("I love this!") == 'Good'
271-
assert classify_sentiment("I hate this.") == 'Bad'
272-
273-
@tanuki.align
274-
def align_score_sentiment():
275-
assert score_sentiment("I like you") == 7
284+
```typescript
285+
import { Finance } from './finance';
286+
import { Tanuki } from 'tanuki.ts';
287+
288+
Tanuki.align((it) => {
289+
it("should extract company names whose stock is increasing", async (expect) => {
290+
const input1 = "Consumer spending makes up a huge fraction of the overall economy. Investors are therefore always looking at consumers to try to gauge whether their financial condition remains healthy. That's a big part of why the stock market saw a bear market in 2022, as some feared that a consumer-led recession would result in much weaker business performance across the sector.\nHowever, that much-anticipated recession hasn't happened yet, and there's still plenty of uncertainty about the future direction of consumer-facing stocks. A pair of earnings reports early Wednesday didn't do much to resolve the debate, as household products giant Procter & Gamble (PG 0.13%) saw its stock rise even as recreational vehicle manufacturer Winnebago Industries (WGO 0.58%) declined.";
291+
expect(await Finance.extractStockWinnersVol6(input1)).toEqual(["Procter & Gamble"]);
292+
})
293+
})
276294
```
277295

278296
By writing a test that encapsulates the expected behaviour of the tanuki-patched function, you declare the contract that the function must fulfill. This enables you to:
@@ -307,7 +325,7 @@ We tested out model distillation using Tanuki using OpenAI models on Squad2, Spi
307325
### Intro
308326
<!-- TOC --><a name="what-is-tanuki-in-plain-words"></a>
309327
#### What is Tanuki in plain words?
310-
Tanuki is a simple and seamless way to create LLM augmented functions in python, which ensure the outputs of the LLMs follow a specific structure. Moreover, the more you call a patched function, the cheaper and faster the execution gets.
328+
Tanuki is a simple and seamless way to create LLM augmented functions in Typescript and Python, which ensure the outputs of the LLMs follow a specific structure. Moreover, the more you call a patched function, the cheaper and faster the execution gets.
311329

312330
<!-- TOC --><a name="how-does-this-compare-to-other-frameworks-like-langchain"></a>
313331
#### How does this compare to other frameworks like LangChain?

jest.config.mjs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@ export default {
33
testEnvironment: 'node',
44
testMatch: ['**/tests/**/*.spec.ts', '**/tests/**/*.test.ts', '**/tests/*.spec.ts', '**/tests/*.test.ts'],
55
transform: {
6-
'^.+\\.tsx?$': 'babel-jest'
6+
'^.+\\.tsx?$': 'ts-jest'
77
},
88
extensionsToTreatAsEsm: ['.ts'],
99
collectCoverageFrom: [
1010
'<rootDir>/src/**/*.ts',
1111
'!<rootDir>/src/types/**/*.ts',
12+
'!<rootDir>/src/models/**/*.ts',
1213
],
1314
globals: {
1415
'ts-jest': {
@@ -17,7 +18,7 @@ export default {
1718
useESM: true,
1819
},
1920
},
20-
moduleNameMapper: {
21-
'^(\\.{1,2}/.*)\\.js$': '$1',
22-
},
21+
//moduleNameMapper: {
22+
// '^(\\.{1,2}/.*)\\.js$': '$1',
23+
//},
2324
};

0 commit comments

Comments
 (0)