Skip to content

Commit

Permalink
Revert "Use collapsible markdown widgets for cells in srcmd (#136)" (#…
Browse files Browse the repository at this point in the history
…138)

This reverts commit 74b1e81.
  • Loading branch information
benjreinhart authored Jul 17, 2024
1 parent 74b1e81 commit a267d50
Show file tree
Hide file tree
Showing 12 changed files with 442 additions and 566 deletions.
21 changes: 5 additions & 16 deletions packages/api/srcbook/examples/getting-started.srcmd
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@

# Getting started

<details>
<summary>package.json</summary>
###### package.json

```json
{
Expand All @@ -13,7 +12,6 @@
}
}
```
</details>

## What are Srcbooks?

Expand All @@ -26,60 +24,51 @@ A Srcbook is composed of **cells**. Currently, there are 4 types of cells:
3. **markdown cell**: what you're reading is a markdown cell. It allows you to easily express ideas with rich markup, rather than code comments, an idea called [literate programming](https://en.wikipedia.org/wiki/Literate_programming).
4. **code cell**: think of these as JS or TS files. You can run them or export objects to be used in other cells.

<details open>
<summary>simple-code.js</summary>
###### simple-code.js

```javascript
// This is a trivial code cell. You can run me by
// clicking 'Run' or using the shortcut `cmd` + `enter`.
console.log("Hello, Srcbook!")
```
</details>

## Dependencies

You can add any external node.js-compatible dependency from [npm](https://www.npmjs.com/). Let's look at an example below by importing the `random-words` library.

You'll need to make sure you install dependencies, which you can do by running the `package.json` cell above.

<details open>
<summary>generate-random-word.js</summary>
###### generate-random-word.js

```javascript
import {generate} from 'random-words';

console.log(generate())
```
</details>

## Importing other cells

Behind the scenes, cells are files of JavaScript or TypeScript code. They are ECMAScript 6 modules. Therefore you can export variables from one file and import them in another.

<details open>
<summary>star-wars.js</summary>
###### star-wars.js

```javascript
export const func = (name) => `I am your father, ${name}`
```
</details>

<details open>
<summary>logger.js</summary>
###### logger.js

```javascript
import {func} from './star-wars.js';

console.log(func("Luke"));
```
</details>

## Using secrets

For security purposes, you should avoid pasting secrets directly into Srcbooks. The mechanism you should leverage is [secrets](/secrets). These are stored securely and are accessed at runtime as environment variables.

Secrets can then be imported in Srcbooks using `process.env.SECRET_NAME`:

```
const API_KEY = process.env.SECRET_API_KEY;
const token = auth(API_KEY);
Expand Down
26 changes: 8 additions & 18 deletions packages/api/srcbook/examples/langgraph-web-agent.srcmd
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@

# LangGraph web agent

<details>
<summary>package.json</summary>
###### package.json

```json
{
Expand All @@ -20,7 +19,6 @@
}
}
```
</details>

## LangGraph tutorial

Expand All @@ -30,23 +28,20 @@ We're going to build an agent that can search the web using the [Tavily Search A

First, let's ensure we've setup the right env variables:

<details open>
<summary>env-check.ts</summary>
###### env-check.ts

```typescript
import assert from 'node:assert';

assert.ok(process.env.OPENAI_API_KEY, 'You need to set OPENAI_API_KEY');
assert.ok(process.env.TAVILY_API_KEY, 'You need to set TAVILY_API_KEY');
```
</details>

## Define the agent

Now, let's define the Agent with LangGraph.js

<details open>
<summary>agent.ts</summary>
###### agent.ts

```typescript
import { HumanMessage } from "@langchain/core/messages";
Expand Down Expand Up @@ -117,13 +112,12 @@ export const memory = SqliteSaver.fromConnString(DB_NAME);
// This compiles it into a LangChain Runnable.
// Note that we're (optionally) passing the memory when compiling the graph
export const app = workflow.compile({ checkpointer: memory });

```
</details>

Now that we've built our app, let's invoke it to first get the weather in SF:

<details open>
<summary>sf-weather.ts</summary>
###### sf-weather.ts

```typescript
import {app} from './agent.ts';
Expand All @@ -140,14 +134,12 @@ const finalState = await app.invoke(

console.log(finalState.messages[finalState.messages.length - 1].content)
```
</details>

Now when we pass the same `thread_id`, in this case `"42"`, the conversation context is retained via the saved state that we've set in a local sqliteDB (i.e. stored list of messages).

Also, in this next example, we demonstrate streaming output.

<details open>
<summary>ny-weather.ts</summary>
###### ny-weather.ts

```typescript
import {app} from './agent.ts';
Expand All @@ -160,19 +152,17 @@ const nextState = await app.invoke(

console.log(nextState.messages[nextState.messages.length - 1].content);
```
</details>

## Clear memory

The memory was saved in the sqlite db `./langGraph.db`. If you want to clear it, run the following cell

<details open>
<summary>clear.ts</summary>
###### clear.ts

```typescript
import {DB_NAME} from './agent.ts';
import fs from 'node:fs';
// I can't find good documentation on the memory module, so let's apply the nuclear method

fs.rmSync(DB_NAME);
```
</details>
21 changes: 6 additions & 15 deletions packages/api/srcbook/examples/websockets.srcmd
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@

# Intro to WebSockets

<details>
<summary>package.json</summary>
###### package.json

```json
{
Expand All @@ -13,7 +12,6 @@
}
}
```
</details>

This Srcbook is a fun demonstration of building a simple WebSocket client and server in Node.js using the [ws library](https://github.com/websockets/ws). We'll explore the basic concepts of communicating over WebSockets and showcase Srcbook's ability to host long-running processes.

Expand All @@ -33,8 +31,7 @@ One of the most popular libraries for WebSockets in Node.js is the [ws library](

Below we implement a simple WebSocket _server_ using `ws`.

<details open>
<summary>simple-server.js</summary>
###### simple-server.js

```javascript
import { WebSocketServer } from 'ws';
Expand All @@ -49,14 +46,12 @@ wss.on('connection', (socket) => {
console.log("New client connected")
});
```
</details>

This simple server does nothing more than wait for incoming connections and log the messages it receives.

Next, we need a _client_ to connect and send messages to it. Note the client is running in a Node.js process, not in the browser. Backends communicate over WebSockets too!

<details open>
<summary>simple-client.js</summary>
###### simple-client.js

```javascript
import WebSocket from 'ws';
Expand All @@ -68,17 +63,16 @@ ws.on('open', () => {
ws.send('Hello from simple-client.js');
ws.close();
});

```
</details>

Our simple client establishes a connection with the server, sends one message, and closes the connection. To run this example, first run the server and then run the client. Output is logged under the simple-server.js cell above.

## Stateful connections

The example above is not terribly interesting. WebSockets become more useful when the server tracks open connections and sends messages to the client.

<details open>
<summary>stateful-server.js</summary>
###### stateful-server.js

```javascript
import { WebSocketServer } from 'ws';
Expand Down Expand Up @@ -138,10 +132,8 @@ wss.on('connection', (socket) => {
});
});
```
</details>

<details open>
<summary>client.js</summary>
###### client.js

```javascript
import WebSocket from 'ws';
Expand Down Expand Up @@ -183,7 +175,6 @@ client2.close();

console.log("Shutting down");
```
</details>

## Explanation

Expand Down
Loading

0 comments on commit a267d50

Please sign in to comment.