-
-
Notifications
You must be signed in to change notification settings - Fork 170
Start of Python and TypeScript DSL #715
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
1de7fe3
10ecaf2
92c200f
e892d2d
5560cd8
1a6df2c
161b6b8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,116 @@ | ||||||
| # N::Chapter { | ||||||
| # chapter_index: I64 | ||||||
| # } | ||||||
| # | ||||||
| # N::SubChapter { | ||||||
| # title: String, | ||||||
| # content: String | ||||||
| # } | ||||||
| # | ||||||
| # E::Contains { | ||||||
| # From: Chapter, | ||||||
| # To: SubChapter, | ||||||
| # Properties: { | ||||||
| # } | ||||||
| # } | ||||||
| # | ||||||
| # V::Embedding { | ||||||
| # chunk: String | ||||||
| # } | ||||||
| # | ||||||
| # E::EmbeddingOf { | ||||||
| # From: SubChapter, | ||||||
| # To: Embedding, | ||||||
| # Properties: { | ||||||
| # chunk: String | ||||||
| # } | ||||||
| # } | ||||||
|
|
||||||
| # QUERY loaddocs_rag(chapters: [{ id: I64, subchapters: [{ title: String, content: String, chunks: [{chunk: String, vector: [F64]}]}] }]) => | ||||||
| # FOR {id, subchapters} IN chapters { | ||||||
| # chapter_node <- AddN<Chapter>({ chapter_index: id }) | ||||||
| # FOR {title, content, chunks} IN subchapters { | ||||||
| # subchapter_node <- AddN<SubChapter>({ title: title, content: content }) | ||||||
| # AddE<Contains>::From(chapter_node)::To(subchapter_node) | ||||||
| # FOR {chunk, vector} IN chunks { | ||||||
| # vec <- AddV<Embedding>(vector) | ||||||
| # AddE<EmbeddingOf>({chunk: chunk})::From(subchapter_node)::To(vec) | ||||||
| # } | ||||||
| # } | ||||||
| # } | ||||||
| # RETURN "Success" | ||||||
|
|
||||||
| # QUERY searchdocs_rag(query: [F64], k: I32) => | ||||||
| # vecs <- SearchV<Embedding>(query, k) | ||||||
| # subchapters <- vecs::In<EmbeddingOf> | ||||||
| # RETURN subchapters::{title, content} | ||||||
|
|
||||||
| # QUERY edge_node() => | ||||||
| # e <- N<Chapter>::OutE<Contains> | ||||||
| # RETURN e | ||||||
|
|
||||||
| # QUERY edge_node_id(id: ID) => | ||||||
| # e <- N<Chapter>::OutE<Contains>(id) | ||||||
| # RETURN e | ||||||
| # | ||||||
|
|
||||||
| import helix | ||||||
|
|
||||||
| db = helix.Db() | ||||||
|
|
||||||
| class Chapter(db.Node): | ||||||
| index: helix.I64 | ||||||
|
|
||||||
| db.index(Chapter.index, unique=True) | ||||||
|
|
||||||
| class SubChapter(db.Node): | ||||||
| title: helix.String | ||||||
| content: helix.String | ||||||
|
|
||||||
| embedding: SubChapterEmbedding | ||||||
|
|
||||||
| class SubChapterEmbedding(db.Vector(dimensions=1536, hnsw=helix.cosine)): | ||||||
| pass | ||||||
|
|
||||||
| class Contains(db.Edge[Chapter, SubChapter]): | ||||||
| pass | ||||||
|
|
||||||
| class ArgChapter(helix.Struct): | ||||||
| id: helix.I64 | ||||||
| subchapters: helix.List[ArgSubchapter] | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. syntax:
Suggested change
Prompt To Fix With AIThis is a comment left during a code review.
Path: examples/bookstore.py
Line: 80:80
Comment:
**syntax:** `ArgSubchapter` is defined on line 82 but referenced here as `ArgSubChapter` (capital C)
```suggestion
subchapters: helix.List[ArgSubchapter]
```
How can I resolve this? If you propose a fix, please make it concise. |
||||||
|
|
||||||
| class ArgSubchapter(helix.Struct): | ||||||
| title: helix.String | ||||||
| content: helix.String | ||||||
| chunk: helix.Vector | ||||||
|
|
||||||
| @db.query | ||||||
| def loaddocs_rag(chapters: helix.List[ArgChapter]) -> helix.String: | ||||||
| for c in chapters: | ||||||
| c_node = db.add_node(Chapter(index=c.id)) | ||||||
|
|
||||||
| for sc in c.subchapters: | ||||||
| sc_node = db.add_node(SubChapter( | ||||||
| title=sc.title, | ||||||
| content=sc.content, | ||||||
| embedding=SubChapterEmbedding(sc.chunk) | ||||||
| )) | ||||||
|
|
||||||
| db.add_edge(Contains(from=c_node, to=sc_node)) | ||||||
|
|
||||||
| return "Success" | ||||||
|
|
||||||
| @db.query | ||||||
| def searchdocs_rag(query: helix.Vector, k: helix.I32) -> helix.Iterator[helix.Map[helix.String, helix.Value]]: | ||||||
| # TODO | ||||||
| vecs = db.search_vector(query, k) | ||||||
| chapters = vecs.incoming_nodes[Contains] | ||||||
| return chapters.map(lambda c: {"index": c.index}) | ||||||
|
Comment on lines
+104
to
+108
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. logic: logic doesn't match the commented HelixQL query above (lines 43-46) - should get Prompt To Fix With AIThis is a comment left during a code review.
Path: examples/bookstore.py
Line: 104:108
Comment:
**logic:** logic doesn't match the commented HelixQL query above (lines 43-46) - should get `subchapters` from vectors via `EmbeddingOf` edge, not `chapters` via `Contains`
How can I resolve this? If you propose a fix, please make it concise. |
||||||
|
|
||||||
| @db.query | ||||||
| def edge_node() -> helix.Iterator[Contains]: | ||||||
| return db.nodes[Chapter].outgoing_edges[Contains] | ||||||
|
|
||||||
| @db.query | ||||||
| def edge_node_id(id: helix.Id[Chapter]) -> helix.Iterator[Contains]: | ||||||
| return db.nodes[Chapter](id=id).outgoing_edges[Contains] | ||||||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,72 @@ | ||||||
| import hx from "helix"; | ||||||
|
|
||||||
| const schema = hx.schema(); | ||||||
|
|
||||||
| const Chapter = schema.defineNode("Chapter", { | ||||||
| index: I64, | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. syntax:
Suggested change
Prompt To Fix With AIThis is a comment left during a code review.
Path: examples/bookstore.ts
Line: 6:6
Comment:
**syntax:** `I64` is undefined - should be `hx.I64`
```suggestion
index: hx.I64,
```
How can I resolve this? If you propose a fix, please make it concise. |
||||||
| }); | ||||||
|
|
||||||
| schema.index(Chapter.index, { unique: true }); | ||||||
|
|
||||||
| const SubChapter = schema.defineNode("SubChapter", { | ||||||
| title: hx.String, | ||||||
| content: hx.String, | ||||||
|
|
||||||
| embedding: SubChapterEmbedding, | ||||||
| }); | ||||||
|
|
||||||
| const SubChapterEmbedding = schema.defineVector("SubChapterEmbedding", { | ||||||
| dimensions: 1536, | ||||||
| hnsw: hx.cosine, | ||||||
| }); | ||||||
|
|
||||||
| const Contains = schema.defineEdge("Contains", { | ||||||
| from: Chapter, | ||||||
| to: SubChapter, | ||||||
| }); | ||||||
|
|
||||||
| const ArgChapter = hx.Struct({ | ||||||
| id: hx.I64, | ||||||
| subchapters: hx.List(ArgSubchapter), | ||||||
| }); | ||||||
|
|
||||||
| const ArgSubChapter = hx.Struct({ | ||||||
| title: hx.String, | ||||||
| content: hx.String, | ||||||
| chunk: hx.Vector, | ||||||
| }); | ||||||
|
|
||||||
| const loadDocsRag = schema.query("loaddocs_rag", { | ||||||
| arguments: [hx.List(ArgChapter)], | ||||||
| returns: hx.String, | ||||||
| }, (db, [chapters]) => { | ||||||
| chapters.forEach((c) => { | ||||||
| const cNode = db.addNode(Chapter({ index: c.id })); | ||||||
|
|
||||||
| c.subchapters.forEach((sc) => { | ||||||
| const scNode = db.addNode(SubChapter({ | ||||||
| title: sc.title, | ||||||
| content: sc.content, | ||||||
| embedding: SubChapterEmbedding(sc.chunk), | ||||||
| })); | ||||||
|
|
||||||
| db.addEdge(Contains({ from: cNode, to: scNode })); | ||||||
| }); | ||||||
| }); | ||||||
|
|
||||||
| return "Success"; | ||||||
| }); | ||||||
|
|
||||||
| const edgeNode = schema.query("edge_node", { | ||||||
| arguments: [], | ||||||
| returns: hx.Iterator(Contains), | ||||||
| }, (db, []) => { | ||||||
| return db.nodes[Chapter].outgoingEdges[Contains]; | ||||||
| }); | ||||||
|
|
||||||
| const edgeNodeId = schema.query("edge_node_id", { | ||||||
| arguments: [hx.Id(Chapter)], | ||||||
| returns: hx.Iterator(Contains), | ||||||
| }, (db, [id]) => { | ||||||
| return db.nodes[Chapter]({ id }).outgoingEdges[Contains]; | ||||||
| }); | ||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| { | ||
| "tasks": { | ||
| "dev": "deno run --watch main.ts" | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,85 @@ | ||
| export const ExprKindString = { kind: "String" as const }; | ||
| export const ExprKindI64 = { kind: "I64" as const }; | ||
| export const ExprKindF64 = { kind: "F64" as const }; | ||
| export const ExprKindBoolean = { kind: "Boolean" as const }; | ||
| export const ExprKindVector = { kind: "Vector" as const }; | ||
| export const ExprKindList = (item: ExprKind) => ({ | ||
| kind: "List" as const, | ||
| item, | ||
| }); | ||
| export const ExprKindStruct = (fields: Record<string, ExprKind>) => ({ | ||
| kind: "Struct" as const, | ||
| fields, | ||
| }); | ||
|
|
||
| export type ExprKind = | ||
| & MaybeNamed | ||
| & ( | ||
| | typeof ExprKindString | ||
| | typeof ExprKindI64 | ||
| | typeof ExprKindF64 | ||
| | typeof ExprKindBoolean | ||
| | typeof ExprKindVector | ||
| | { kind: "List"; item: ExprKind } | ||
| | { kind: "Struct"; fields: Record<string, ExprKind> } | ||
| ); | ||
|
|
||
| export type Expr = { | ||
| kind: ExprKind; | ||
| expr: | ||
| | { expr: "Argument"; index: number } | ||
| | { expr: "PropAccess"; target: Expr; field: string } | ||
| | { expr: "Literal"; value: any } | ||
| | { expr: "BinaryOp"; op: string; left: Expr; right: Expr } | ||
| | { expr: "Call"; func: string; args: Expr[] }; | ||
| }; | ||
|
|
||
| export type Statement = | ||
| | { stmt: "Expr"; expr: Expr } | ||
| | { stmt: "Return"; value: Expr }; | ||
|
|
||
| export type Block = Statement[]; | ||
|
|
||
| export type Named = { name: string }; | ||
| export type MaybeNamed = Partial<Named>; | ||
|
|
||
| export type QueryName = string; | ||
| export type Query = Named & { | ||
| arguments: ExprKind[]; | ||
| returns: ExprKind; | ||
| body: Block; | ||
| }; | ||
|
|
||
| export type NodeName = string; | ||
| export type Node = Named & { | ||
| id: typeof ExprKindI64; | ||
| [_: string]: ExprKind; | ||
| }; | ||
|
|
||
| export type EdgeName = string; | ||
| export type Edge = Named & { | ||
| id: typeof ExprKindI64; | ||
| from: NodeName; | ||
| to: NodeName; | ||
| }; | ||
|
|
||
| export const GlobalVectorspaceName = `vectorspace_global` as const; | ||
| export type GlobalVectorspaceName = typeof GlobalVectorspaceName; | ||
| export type GlobalVectorspace = symbol; | ||
|
|
||
| export type VectorspaceName = string; | ||
| export type Vectorspace = Named & { | ||
| dimensions: number; | ||
| hnsw: any; // TODO | ||
| }; | ||
|
|
||
| export type Schema = { | ||
| nodes: Record<NodeName, Node>; | ||
| indices: [{ on: NodeName; field: string; unique: boolean }]; | ||
|
|
||
| edges: Record<EdgeName, Edge>; | ||
|
|
||
| vectorspaces: Record<GlobalVectorspaceName | VectorspaceName, Vectorspace>; | ||
|
|
||
| queries: Record<QueryName, Query>; | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| if (import.meta.main) { | ||
| console.log("it runs!"); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
syntax:
SubChapterEmbeddingused before definition (defined on line 72)Prompt To Fix With AI