alchemy 0.3.1 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -3
- package/lib/ai/document.d.ts +12 -1
- package/lib/ai/document.js +10 -1
- package/lib/ai/index.d.ts +0 -2
- package/lib/ai/index.js +0 -2
- package/lib/alchemy.d.ts +5 -0
- package/lib/alchemy.js +44 -1
- package/lib/apply.js +17 -10
- package/lib/aws/account-id.d.ts +4 -1
- package/lib/aws/account-id.js +1 -1
- package/lib/aws/credentials.d.ts +5 -0
- package/lib/aws/credentials.js +0 -0
- package/lib/aws/oidc/oidc-provider.js +2 -2
- package/lib/aws/role.js +35 -23
- package/lib/cloudflare/account-api-token.d.ts +168 -0
- package/lib/cloudflare/account-api-token.js +179 -0
- package/lib/cloudflare/account-id.d.ts +1 -0
- package/lib/cloudflare/account-id.js +0 -0
- package/lib/cloudflare/api.d.ts +38 -1
- package/lib/cloudflare/api.js +55 -4
- package/lib/cloudflare/assets.d.ts +74 -0
- package/lib/cloudflare/assets.js +73 -0
- package/lib/cloudflare/bindings.d.ts +6 -1
- package/lib/cloudflare/bindings.js +6 -0
- package/lib/cloudflare/bucket.d.ts +118 -3
- package/lib/cloudflare/bucket.js +269 -89
- package/lib/cloudflare/custom-domain.d.ts +75 -0
- package/lib/cloudflare/custom-domain.js +154 -0
- package/lib/cloudflare/{dns.js → dns-records.js} +14 -1
- package/lib/cloudflare/index.d.ts +6 -1
- package/lib/cloudflare/index.js +6 -1
- package/lib/cloudflare/permission-groups.d.ts +78 -0
- package/lib/cloudflare/permission-groups.js +48 -0
- package/lib/cloudflare/r2-rest-state-store.d.ts +2 -1
- package/lib/cloudflare/r2-rest-state-store.js +55 -24
- package/lib/cloudflare/static-site.d.ts +17 -18
- package/lib/cloudflare/static-site.js +19 -10
- package/lib/cloudflare/worker.d.ts +14 -0
- package/lib/cloudflare/worker.js +150 -3
- package/lib/{util/encrypt.d.ts → encrypt.d.ts} +1 -1
- package/lib/{util/encrypt.js → encrypt.js} +1 -1
- package/lib/fs/file-system-state-store.js +1 -1
- package/lib/fs/file.d.ts +18 -0
- package/lib/fs/file.js +6 -0
- package/lib/internal/{providers.d.ts → docs/providers.d.ts} +10 -4
- package/lib/internal/docs/providers.js +196 -0
- package/lib/secret.d.ts +3 -0
- package/lib/secret.js +13 -0
- package/lib/{util/serde.d.ts → serde.d.ts} +1 -1
- package/lib/{util/serde.js → serde.js} +12 -4
- package/lib/test/bun.js +3 -2
- package/lib/util/sha256.d.ts +1 -0
- package/lib/util/sha256.js +4 -0
- package/lib/web/vitepress/config.d.ts +2 -1
- package/lib/web/vitepress/config.js +1 -0
- package/lib/web/vitepress/index.d.ts +1 -0
- package/lib/web/vitepress/index.js +1 -0
- package/lib/web/vitepress/process-front-matter-files.d.ts +18 -0
- package/lib/web/vitepress/process-front-matter-files.js +68 -0
- package/lib/web/vitepress/vitepress.js +3 -2
- package/package.json +8 -4
- package/src/ai/document.ts +26 -2
- package/src/ai/index.ts +0 -2
- package/src/alchemy.ts +56 -2
- package/src/apply.ts +21 -20
- package/src/aws/account-id.ts +6 -2
- package/src/aws/credentials.ts +6 -0
- package/src/aws/oidc/oidc-provider.ts +17 -17
- package/src/aws/role.ts +68 -54
- package/src/cloudflare/account-api-token.ts +365 -0
- package/src/cloudflare/account-id.ts +0 -0
- package/src/cloudflare/api.ts +88 -17
- package/src/cloudflare/assets.ts +155 -0
- package/src/cloudflare/bindings.ts +11 -2
- package/src/cloudflare/bucket.ts +493 -133
- package/src/cloudflare/custom-domain.ts +318 -0
- package/src/cloudflare/{dns.ts → dns-records.ts} +36 -22
- package/src/cloudflare/index.ts +6 -1
- package/src/cloudflare/permission-groups.ts +137 -0
- package/src/cloudflare/r2-rest-state-store.ts +87 -42
- package/src/cloudflare/static-site.ts +20 -32
- package/src/cloudflare/worker.ts +253 -5
- package/src/dns/import-dns.ts +4 -4
- package/src/{util/encrypt.ts → encrypt.ts} +7 -10
- package/src/fs/file-system-state-store.ts +5 -5
- package/src/fs/file.ts +29 -0
- package/src/internal/docs/providers.ts +281 -0
- package/src/secret.ts +16 -0
- package/src/{util/serde.ts → serde.ts} +16 -10
- package/src/test/bun.ts +8 -7
- package/src/util/sha256.ts +5 -0
- package/src/web/vitepress/config.ts +3 -1
- package/src/web/vitepress/index.ts +1 -0
- package/src/web/vitepress/process-front-matter-files.ts +98 -0
- package/src/web/vitepress/vitepress.ts +3 -2
- package/lib/ai/approve.d.ts +0 -99
- package/lib/ai/approve.js +0 -76
- package/lib/ai/review.d.ts +0 -122
- package/lib/ai/review.js +0 -101
- package/lib/internal/getting-started.d.ts +0 -21
- package/lib/internal/getting-started.js +0 -87
- package/lib/internal/index.d.ts +0 -3
- package/lib/internal/index.js +0 -3
- package/lib/internal/providers.js +0 -172
- package/lib/internal/tutorial.d.ts +0 -104
- package/lib/internal/tutorial.js +0 -251
- package/src/ai/approve.ts +0 -163
- package/src/ai/review.ts +0 -213
- package/src/internal/getting-started.ts +0 -115
- package/src/internal/index.ts +0 -3
- package/src/internal/providers.ts +0 -241
- package/src/internal/tutorial.ts +0 -392
- /package/lib/cloudflare/{dns.d.ts → dns-records.d.ts} +0 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
/**
|
|
4
|
+
* Process markdown files with frontmatter to generate navigation items
|
|
5
|
+
* @param directoryPath The directory containing markdown files
|
|
6
|
+
* @param linkPrefix The prefix for navigation links
|
|
7
|
+
* @returns Sorted array of navigation items with text and link properties
|
|
8
|
+
*/
|
|
9
|
+
export async function processFrontmatterFiles(
|
|
10
|
+
directoryPath: string,
|
|
11
|
+
linkPrefix: string
|
|
12
|
+
): Promise<
|
|
13
|
+
{
|
|
14
|
+
text: string;
|
|
15
|
+
link: string;
|
|
16
|
+
items?: {
|
|
17
|
+
text: string;
|
|
18
|
+
link: string;
|
|
19
|
+
items?: { text: string; link: string }[];
|
|
20
|
+
}[];
|
|
21
|
+
}[]
|
|
22
|
+
> {
|
|
23
|
+
const entries = await fs.readdir(directoryPath, { withFileTypes: true });
|
|
24
|
+
|
|
25
|
+
const processedEntries = await Promise.all(
|
|
26
|
+
entries
|
|
27
|
+
.filter((entry) => !entry.name.endsWith("index.md"))
|
|
28
|
+
.map(async (entry) => {
|
|
29
|
+
const fullPath = path.join(directoryPath, entry.name);
|
|
30
|
+
|
|
31
|
+
if (entry.isDirectory()) {
|
|
32
|
+
// Process subdirectory recursively
|
|
33
|
+
const items = await processFrontmatterFiles(
|
|
34
|
+
fullPath,
|
|
35
|
+
`${linkPrefix}/${entry.name}`
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
// Create section for subdirectory
|
|
39
|
+
return {
|
|
40
|
+
text: entry.name.charAt(0).toUpperCase() + entry.name.slice(1),
|
|
41
|
+
collapsed: false,
|
|
42
|
+
items,
|
|
43
|
+
order: 10000, // Default order for directories
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Process markdown file
|
|
48
|
+
if (!entry.name.endsWith(".md")) {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const content = await fs.readFile(fullPath, "utf-8");
|
|
53
|
+
const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
54
|
+
let order = 10000;
|
|
55
|
+
let title;
|
|
56
|
+
|
|
57
|
+
if (frontmatterMatch) {
|
|
58
|
+
const frontmatter = frontmatterMatch[1];
|
|
59
|
+
const orderMatch = frontmatter.match(/order:\s*(\d+)/);
|
|
60
|
+
if (orderMatch) {
|
|
61
|
+
order = parseInt(orderMatch[1]);
|
|
62
|
+
}
|
|
63
|
+
const titleMatch = frontmatter.match(/title:\s*(.+)/);
|
|
64
|
+
if (titleMatch) {
|
|
65
|
+
title = titleMatch[1].trim();
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// If no title in frontmatter, try to get first heading
|
|
70
|
+
if (!title) {
|
|
71
|
+
const headingMatch = content.match(/^#\s+(.+)$/m);
|
|
72
|
+
if (headingMatch) {
|
|
73
|
+
title = headingMatch[1].trim();
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Fall back to filename if no title found
|
|
78
|
+
if (!title) {
|
|
79
|
+
const name = entry.name.replace(".md", "");
|
|
80
|
+
title = name.charAt(0).toUpperCase() + name.slice(1);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return {
|
|
84
|
+
text: title,
|
|
85
|
+
link: `${linkPrefix}/${entry.name}`,
|
|
86
|
+
order,
|
|
87
|
+
};
|
|
88
|
+
})
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
// Filter out null entries and sort by order
|
|
92
|
+
return processedEntries
|
|
93
|
+
.filter((entry) => entry !== null)
|
|
94
|
+
.sort((a, b) => a.order - b.order)
|
|
95
|
+
.map(({ text, link, items }) =>
|
|
96
|
+
items ? { text, items, collapsed: true } : { text, link }
|
|
97
|
+
) as any;
|
|
98
|
+
}
|
|
@@ -117,8 +117,9 @@ export const VitepressProject = Resource(
|
|
|
117
117
|
try {
|
|
118
118
|
if (props.delete !== false) {
|
|
119
119
|
if (await fs.exists(dir)) {
|
|
120
|
-
|
|
121
|
-
|
|
120
|
+
await fs.rm(dir, { recursive: true, force: true });
|
|
121
|
+
// // Delete the entire project directory
|
|
122
|
+
// await execAsync(`rm -rf ${dir}`);
|
|
122
123
|
}
|
|
123
124
|
}
|
|
124
125
|
} catch (error) {
|
package/lib/ai/approve.d.ts
DELETED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import type { CoreMessage } from "ai";
|
|
2
|
-
/**
|
|
3
|
-
* Properties for approving or denying content
|
|
4
|
-
*/
|
|
5
|
-
export interface ApproveProps {
|
|
6
|
-
/**
|
|
7
|
-
* Content to be reviewed
|
|
8
|
-
* Use alchemy template literals to include file context:
|
|
9
|
-
* @example
|
|
10
|
-
* content: await alchemy`
|
|
11
|
-
* Review this code:
|
|
12
|
-
* ${alchemy.file("src/api.ts")}
|
|
13
|
-
* `
|
|
14
|
-
*
|
|
15
|
-
* Required unless messages are provided
|
|
16
|
-
*/
|
|
17
|
-
content?: string;
|
|
18
|
-
/**
|
|
19
|
-
* Prompt for the approval decision
|
|
20
|
-
* This should include specific criteria for approval or denial
|
|
21
|
-
* @example
|
|
22
|
-
* prompt: "Approve this code if it follows security best practices and has proper error handling."
|
|
23
|
-
*
|
|
24
|
-
* Required unless messages are provided
|
|
25
|
-
*/
|
|
26
|
-
prompt?: string;
|
|
27
|
-
/**
|
|
28
|
-
* System prompt for the model
|
|
29
|
-
* This is used to provide instructions to the model about how to make the decision
|
|
30
|
-
*/
|
|
31
|
-
system?: string;
|
|
32
|
-
/**
|
|
33
|
-
* Message history for the conversation
|
|
34
|
-
* If provided, this will be used instead of the prompt and content
|
|
35
|
-
*/
|
|
36
|
-
messages?: CoreMessage[];
|
|
37
|
-
/**
|
|
38
|
-
* Temperature for controlling randomness in generation.
|
|
39
|
-
* Higher values (e.g., 0.8) make output more random,
|
|
40
|
-
* lower values (e.g., 0.2) make it more deterministic.
|
|
41
|
-
* @default 0.2 (lower for more consistent decisions)
|
|
42
|
-
*/
|
|
43
|
-
temperature?: number;
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* Result of the approval process
|
|
47
|
-
*/
|
|
48
|
-
export interface ApprovalResult {
|
|
49
|
-
/**
|
|
50
|
-
* Whether the content was approved
|
|
51
|
-
*/
|
|
52
|
-
approved: boolean;
|
|
53
|
-
/**
|
|
54
|
-
* Explanation for the decision
|
|
55
|
-
*/
|
|
56
|
-
explanation: string;
|
|
57
|
-
/**
|
|
58
|
-
* Suggestions for improvement if denied
|
|
59
|
-
*/
|
|
60
|
-
suggestions?: string[];
|
|
61
|
-
/**
|
|
62
|
-
* Updated message history with the approval response appended
|
|
63
|
-
*/
|
|
64
|
-
messages: CoreMessage[];
|
|
65
|
-
}
|
|
66
|
-
export type Approve = ApprovalResult;
|
|
67
|
-
/**
|
|
68
|
-
* Approves or denies content based on a prompt or message history
|
|
69
|
-
*
|
|
70
|
-
* @example
|
|
71
|
-
* // Approve or deny a code file
|
|
72
|
-
* const result = await Approve("code-approval", {
|
|
73
|
-
* content: await alchemy`
|
|
74
|
-
* Review this API implementation:
|
|
75
|
-
* ${alchemy.file("src/api.ts")}
|
|
76
|
-
* `,
|
|
77
|
-
* prompt: "Approve this code if it follows security best practices and has proper error handling."
|
|
78
|
-
* });
|
|
79
|
-
*
|
|
80
|
-
* if (result.approved) {
|
|
81
|
-
* console.log("Content approved:", result.explanation);
|
|
82
|
-
* } else {
|
|
83
|
-
* console.log("Content denied:", result.explanation);
|
|
84
|
-
* console.log("Suggestions:", result.suggestions);
|
|
85
|
-
* }
|
|
86
|
-
*
|
|
87
|
-
* @example
|
|
88
|
-
* // Approve or deny using message history
|
|
89
|
-
* const result = await Approve("doc-approval-with-history", {
|
|
90
|
-
* content: "This is the content to review",
|
|
91
|
-
* prompt: "Approve this documentation if it is clear and accurate",
|
|
92
|
-
* messages: [
|
|
93
|
-
* { role: "user", content: "Can you review this documentation?" },
|
|
94
|
-
* { role: "assistant", content: "Yes, I'd be happy to review it." },
|
|
95
|
-
* { role: "user", content: "Please check for clarity and accuracy." }
|
|
96
|
-
* ]
|
|
97
|
-
* });
|
|
98
|
-
*/
|
|
99
|
-
export declare function Approve(id: string, props: ApproveProps): Promise<ApprovalResult>;
|
package/lib/ai/approve.js
DELETED
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
import { type } from "arktype";
|
|
2
|
-
import { Data } from "./data";
|
|
3
|
-
/**
|
|
4
|
-
* Default system prompt for approval decisions
|
|
5
|
-
*/
|
|
6
|
-
const DEFAULT_APPROVE_SYSTEM_PROMPT = `You are an expert content reviewer tasked with approving or denying content based on specific criteria.
|
|
7
|
-
|
|
8
|
-
Your role is to:
|
|
9
|
-
1. Carefully evaluate the content against the provided criteria
|
|
10
|
-
2. Make a clear decision to approve or deny the content
|
|
11
|
-
3. Provide a detailed explanation for your decision
|
|
12
|
-
4. If denying, offer specific suggestions for improvement
|
|
13
|
-
|
|
14
|
-
Be objective, thorough, and fair in your assessment.`;
|
|
15
|
-
/**
|
|
16
|
-
* Approves or denies content based on a prompt or message history
|
|
17
|
-
*
|
|
18
|
-
* @example
|
|
19
|
-
* // Approve or deny a code file
|
|
20
|
-
* const result = await Approve("code-approval", {
|
|
21
|
-
* content: await alchemy`
|
|
22
|
-
* Review this API implementation:
|
|
23
|
-
* ${alchemy.file("src/api.ts")}
|
|
24
|
-
* `,
|
|
25
|
-
* prompt: "Approve this code if it follows security best practices and has proper error handling."
|
|
26
|
-
* });
|
|
27
|
-
*
|
|
28
|
-
* if (result.approved) {
|
|
29
|
-
* console.log("Content approved:", result.explanation);
|
|
30
|
-
* } else {
|
|
31
|
-
* console.log("Content denied:", result.explanation);
|
|
32
|
-
* console.log("Suggestions:", result.suggestions);
|
|
33
|
-
* }
|
|
34
|
-
*
|
|
35
|
-
* @example
|
|
36
|
-
* // Approve or deny using message history
|
|
37
|
-
* const result = await Approve("doc-approval-with-history", {
|
|
38
|
-
* content: "This is the content to review",
|
|
39
|
-
* prompt: "Approve this documentation if it is clear and accurate",
|
|
40
|
-
* messages: [
|
|
41
|
-
* { role: "user", content: "Can you review this documentation?" },
|
|
42
|
-
* { role: "assistant", content: "Yes, I'd be happy to review it." },
|
|
43
|
-
* { role: "user", content: "Please check for clarity and accuracy." }
|
|
44
|
-
* ]
|
|
45
|
-
* });
|
|
46
|
-
*/
|
|
47
|
-
export async function Approve(id, props) {
|
|
48
|
-
// Create messages array if not provided
|
|
49
|
-
const messages = props.messages ||
|
|
50
|
-
(props.content && props.prompt
|
|
51
|
-
? [
|
|
52
|
-
{
|
|
53
|
-
role: "user",
|
|
54
|
-
content: `${props.content}\n\n${props.prompt}`,
|
|
55
|
-
},
|
|
56
|
-
]
|
|
57
|
-
: []);
|
|
58
|
-
if (messages.length === 0) {
|
|
59
|
-
throw new Error("Either messages or both content and prompt must be provided");
|
|
60
|
-
}
|
|
61
|
-
const data = await Data(id, {
|
|
62
|
-
schema: type({
|
|
63
|
-
approved: "boolean",
|
|
64
|
-
explanation: "string",
|
|
65
|
-
suggestions: "string[]?",
|
|
66
|
-
}),
|
|
67
|
-
messages,
|
|
68
|
-
system: props.system || DEFAULT_APPROVE_SYSTEM_PROMPT,
|
|
69
|
-
temperature: props.temperature ?? 0.2,
|
|
70
|
-
});
|
|
71
|
-
// Return the result with updated messages from Data
|
|
72
|
-
return {
|
|
73
|
-
...data.object,
|
|
74
|
-
messages: data.messages,
|
|
75
|
-
};
|
|
76
|
-
}
|
package/lib/ai/review.d.ts
DELETED
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
import { type CoreMessage } from "ai";
|
|
2
|
-
import type { Context } from "../context";
|
|
3
|
-
import { Resource } from "../resource";
|
|
4
|
-
import type { Secret } from "../secret";
|
|
5
|
-
import { type ModelConfig } from "./client";
|
|
6
|
-
/**
|
|
7
|
-
* Properties for creating or updating a Review
|
|
8
|
-
*/
|
|
9
|
-
export interface ReviewProps {
|
|
10
|
-
/**
|
|
11
|
-
* Content to be reviewed
|
|
12
|
-
* Use alchemy template literals to include file context:
|
|
13
|
-
* @example
|
|
14
|
-
* content: await alchemy`
|
|
15
|
-
* Review this code:
|
|
16
|
-
* ${alchemy.file("src/api.ts")}
|
|
17
|
-
* `
|
|
18
|
-
*
|
|
19
|
-
* Required unless messages are provided
|
|
20
|
-
*/
|
|
21
|
-
content?: string;
|
|
22
|
-
/**
|
|
23
|
-
* Prompt for the review
|
|
24
|
-
* This should include specific instructions for the review
|
|
25
|
-
* @example
|
|
26
|
-
* prompt: "Review this code for security vulnerabilities, performance issues, and best practices."
|
|
27
|
-
*
|
|
28
|
-
* Required unless messages are provided
|
|
29
|
-
*/
|
|
30
|
-
prompt?: string;
|
|
31
|
-
/**
|
|
32
|
-
* Message history for the conversation
|
|
33
|
-
* If provided, this will be used instead of the prompt and content
|
|
34
|
-
*/
|
|
35
|
-
messages?: CoreMessage[];
|
|
36
|
-
/**
|
|
37
|
-
* System prompt for the model
|
|
38
|
-
* This is used to provide instructions to the model about how to format the response
|
|
39
|
-
* The default system prompt instructs the model to act as a reviewer
|
|
40
|
-
*/
|
|
41
|
-
system?: string;
|
|
42
|
-
/**
|
|
43
|
-
* AI API key to use for generating content
|
|
44
|
-
* If not provided, will use OPENAI_API_KEY environment variable
|
|
45
|
-
*/
|
|
46
|
-
apiKey?: Secret;
|
|
47
|
-
/**
|
|
48
|
-
* Model configuration
|
|
49
|
-
*/
|
|
50
|
-
model?: ModelConfig;
|
|
51
|
-
/**
|
|
52
|
-
* Temperature for controlling randomness in generation.
|
|
53
|
-
* Higher values (e.g., 0.8) make output more random,
|
|
54
|
-
* lower values (e.g., 0.2) make it more deterministic.
|
|
55
|
-
* @default 0.7
|
|
56
|
-
*/
|
|
57
|
-
temperature?: number;
|
|
58
|
-
/**
|
|
59
|
-
* Maximum number of tokens to generate.
|
|
60
|
-
* Higher values allow for longer documents but may increase cost and generation time.
|
|
61
|
-
* @default 10000
|
|
62
|
-
*/
|
|
63
|
-
maxTokens?: number;
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* Output returned after Review creation/update
|
|
67
|
-
*/
|
|
68
|
-
export interface Review extends ReviewProps, Resource<"ai::Review"> {
|
|
69
|
-
/**
|
|
70
|
-
* Content of the review
|
|
71
|
-
*/
|
|
72
|
-
content: string;
|
|
73
|
-
/**
|
|
74
|
-
* Updated message history with the review response appended
|
|
75
|
-
*/
|
|
76
|
-
messages: CoreMessage[];
|
|
77
|
-
/**
|
|
78
|
-
* Time at which the review was created
|
|
79
|
-
*/
|
|
80
|
-
createdAt: number;
|
|
81
|
-
/**
|
|
82
|
-
* Time at which the review was last updated
|
|
83
|
-
*/
|
|
84
|
-
updatedAt: number;
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* Creates or updates a Review resource
|
|
88
|
-
*
|
|
89
|
-
* @example
|
|
90
|
-
* // Create a review of a code file
|
|
91
|
-
* const codeReview = await Review("api-review", {
|
|
92
|
-
* content: await alchemy`
|
|
93
|
-
* Review this API implementation:
|
|
94
|
-
* ${alchemy.file("src/api.ts")}
|
|
95
|
-
* `,
|
|
96
|
-
* prompt: "Review this API implementation for security vulnerabilities, performance issues, and best practices. Suggest improvements and alternative approaches."
|
|
97
|
-
* });
|
|
98
|
-
*
|
|
99
|
-
* @example
|
|
100
|
-
* // Create a review of a document
|
|
101
|
-
* const docReview = await Review("tutorial-review", {
|
|
102
|
-
* content: await alchemy`
|
|
103
|
-
* Review this tutorial:
|
|
104
|
-
* ${alchemy.file("docs/tutorials/getting-started.md")}
|
|
105
|
-
* `,
|
|
106
|
-
* prompt: "Review this tutorial for clarity, accuracy, and completeness. Suggest improvements to make it more user-friendly."
|
|
107
|
-
* });
|
|
108
|
-
*
|
|
109
|
-
* @example
|
|
110
|
-
* // Create a review with message history
|
|
111
|
-
* const reviewWithHistory = await Review("code-review-iteration-2", {
|
|
112
|
-
* content: "Updated code implementation",
|
|
113
|
-
* prompt: "Review this updated implementation",
|
|
114
|
-
* messages: [
|
|
115
|
-
* { role: "user", content: "Can you review my code?" },
|
|
116
|
-
* { role: "assistant", content: "I'll review your code. Please share it." },
|
|
117
|
-
* { role: "user", content: "Here's my implementation: [code]" },
|
|
118
|
-
* { role: "assistant", content: "Here's my review of your code: [previous review]" }
|
|
119
|
-
* ]
|
|
120
|
-
* });
|
|
121
|
-
*/
|
|
122
|
-
export declare const Review: (((this: any, id: string, props?: {}) => never) & (new (_: never) => never)) | ((this: Context<Review>, id: string, props: ReviewProps) => Promise<Review>);
|
package/lib/ai/review.js
DELETED
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
import { generateText } from "ai";
|
|
2
|
-
import { Resource } from "../resource";
|
|
3
|
-
import { createModel, withRateLimitRetry } from "./client";
|
|
4
|
-
/**
|
|
5
|
-
* Default system prompt for review generation
|
|
6
|
-
*/
|
|
7
|
-
const DEFAULT_REVIEW_SYSTEM_PROMPT = `You are an expert code reviewer and technical writer. Your task is to provide a thorough review of the provided content. Your review should include:
|
|
8
|
-
|
|
9
|
-
1. A high-level summary of the content
|
|
10
|
-
2. Detailed feedback on the content's quality, accuracy, and completeness
|
|
11
|
-
3. Specific suggestions for improvement
|
|
12
|
-
4. Alternative approaches or solutions where applicable
|
|
13
|
-
5. Best practices that should be followed
|
|
14
|
-
6. Potential issues or concerns that should be addressed
|
|
15
|
-
|
|
16
|
-
Provide your review in a clear, well-structured format.`;
|
|
17
|
-
/**
|
|
18
|
-
* Creates or updates a Review resource
|
|
19
|
-
*
|
|
20
|
-
* @example
|
|
21
|
-
* // Create a review of a code file
|
|
22
|
-
* const codeReview = await Review("api-review", {
|
|
23
|
-
* content: await alchemy`
|
|
24
|
-
* Review this API implementation:
|
|
25
|
-
* ${alchemy.file("src/api.ts")}
|
|
26
|
-
* `,
|
|
27
|
-
* prompt: "Review this API implementation for security vulnerabilities, performance issues, and best practices. Suggest improvements and alternative approaches."
|
|
28
|
-
* });
|
|
29
|
-
*
|
|
30
|
-
* @example
|
|
31
|
-
* // Create a review of a document
|
|
32
|
-
* const docReview = await Review("tutorial-review", {
|
|
33
|
-
* content: await alchemy`
|
|
34
|
-
* Review this tutorial:
|
|
35
|
-
* ${alchemy.file("docs/tutorials/getting-started.md")}
|
|
36
|
-
* `,
|
|
37
|
-
* prompt: "Review this tutorial for clarity, accuracy, and completeness. Suggest improvements to make it more user-friendly."
|
|
38
|
-
* });
|
|
39
|
-
*
|
|
40
|
-
* @example
|
|
41
|
-
* // Create a review with message history
|
|
42
|
-
* const reviewWithHistory = await Review("code-review-iteration-2", {
|
|
43
|
-
* content: "Updated code implementation",
|
|
44
|
-
* prompt: "Review this updated implementation",
|
|
45
|
-
* messages: [
|
|
46
|
-
* { role: "user", content: "Can you review my code?" },
|
|
47
|
-
* { role: "assistant", content: "I'll review your code. Please share it." },
|
|
48
|
-
* { role: "user", content: "Here's my implementation: [code]" },
|
|
49
|
-
* { role: "assistant", content: "Here's my review of your code: [previous review]" }
|
|
50
|
-
* ]
|
|
51
|
-
* });
|
|
52
|
-
*/
|
|
53
|
-
export const Review = Resource("ai::Review", async function (id, props) {
|
|
54
|
-
if (this.phase === "delete") {
|
|
55
|
-
return this.destroy();
|
|
56
|
-
}
|
|
57
|
-
// Use provided system prompt or default
|
|
58
|
-
const system = props.system || DEFAULT_REVIEW_SYSTEM_PROMPT;
|
|
59
|
-
// Create messages array if not provided
|
|
60
|
-
const messages = props.messages ||
|
|
61
|
-
(props.content && props.prompt
|
|
62
|
-
? [
|
|
63
|
-
{
|
|
64
|
-
role: "user",
|
|
65
|
-
content: `${props.content}\n\n${props.prompt}`,
|
|
66
|
-
},
|
|
67
|
-
]
|
|
68
|
-
: []);
|
|
69
|
-
if (messages.length === 0) {
|
|
70
|
-
throw new Error("Either messages or both content and prompt must be provided");
|
|
71
|
-
}
|
|
72
|
-
// Generate review content with rate limit retry
|
|
73
|
-
const { text } = await withRateLimitRetry(async () => {
|
|
74
|
-
return generateText({
|
|
75
|
-
model: createModel(props),
|
|
76
|
-
messages,
|
|
77
|
-
system,
|
|
78
|
-
maxTokens: props.maxTokens || 8192,
|
|
79
|
-
providerOptions: props.model?.options,
|
|
80
|
-
...(props.temperature === undefined
|
|
81
|
-
? {}
|
|
82
|
-
: { temperature: props.temperature }),
|
|
83
|
-
});
|
|
84
|
-
});
|
|
85
|
-
// Create updated message history with the AI's response
|
|
86
|
-
const updatedMessages = [
|
|
87
|
-
...messages,
|
|
88
|
-
{
|
|
89
|
-
role: "assistant",
|
|
90
|
-
content: text,
|
|
91
|
-
},
|
|
92
|
-
];
|
|
93
|
-
// Return the review with the direct text from the LLM and updated messages
|
|
94
|
-
return this({
|
|
95
|
-
...props,
|
|
96
|
-
content: text,
|
|
97
|
-
messages: updatedMessages,
|
|
98
|
-
createdAt: Date.now(),
|
|
99
|
-
updatedAt: Date.now(),
|
|
100
|
-
});
|
|
101
|
-
});
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { Document } from "../ai";
|
|
2
|
-
import type { ModelConfig } from "../ai/client";
|
|
3
|
-
import type { Folder } from "../fs";
|
|
4
|
-
export interface GettingStartedProps {
|
|
5
|
-
/**
|
|
6
|
-
* The output directory for the getting started document.
|
|
7
|
-
*/
|
|
8
|
-
path: string | Folder;
|
|
9
|
-
/**
|
|
10
|
-
* The prompt to use for generating the getting started guide.
|
|
11
|
-
* This should include specific details about the product or framework.
|
|
12
|
-
*/
|
|
13
|
-
prompt: string;
|
|
14
|
-
/**
|
|
15
|
-
* Optional model configuration for generating the getting started guide.
|
|
16
|
-
* Defaults to Claude 3.5 Sonnet.
|
|
17
|
-
*/
|
|
18
|
-
model?: ModelConfig;
|
|
19
|
-
}
|
|
20
|
-
export type GettingStarted = Document;
|
|
21
|
-
export declare function GettingStarted({ path: outFile, prompt, model, }: GettingStartedProps): Promise<Document>;
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import { Document } from "../ai";
|
|
2
|
-
import { alchemy } from "../alchemy";
|
|
3
|
-
export async function GettingStarted({ path: outFile, prompt, model = {
|
|
4
|
-
id: "claude-3-5-sonnet-latest",
|
|
5
|
-
provider: "anthropic",
|
|
6
|
-
}, }) {
|
|
7
|
-
return Document(`docs/getting-started`, {
|
|
8
|
-
title: "Getting Started Guide",
|
|
9
|
-
path: typeof outFile === "string" ? outFile : outFile.path,
|
|
10
|
-
model,
|
|
11
|
-
prompt: await alchemy `
|
|
12
|
-
You are a technical writer creating a getting started guide.
|
|
13
|
-
|
|
14
|
-
${prompt}
|
|
15
|
-
|
|
16
|
-
If you need a template structure to follow, use this format:
|
|
17
|
-
|
|
18
|
-
# Getting Started with [Product/Framework Name]
|
|
19
|
-
|
|
20
|
-
(Brief introduction to the product/framework)
|
|
21
|
-
|
|
22
|
-
## Installation
|
|
23
|
-
|
|
24
|
-
\`\`\`bash
|
|
25
|
-
# Installation command
|
|
26
|
-
\`\`\`
|
|
27
|
-
|
|
28
|
-
## Creating Your First Project
|
|
29
|
-
|
|
30
|
-
(Step-by-step guide to creating a basic project)
|
|
31
|
-
|
|
32
|
-
\`\`\`ts
|
|
33
|
-
// Example of a simple project
|
|
34
|
-
\`\`\`
|
|
35
|
-
|
|
36
|
-
## Core Concepts
|
|
37
|
-
|
|
38
|
-
### [Concept 1]
|
|
39
|
-
|
|
40
|
-
(Explanation of the first core concept)
|
|
41
|
-
|
|
42
|
-
\`\`\`ts
|
|
43
|
-
// Example of using the concept
|
|
44
|
-
\`\`\`
|
|
45
|
-
|
|
46
|
-
### [Concept 2]
|
|
47
|
-
|
|
48
|
-
(Explanation of the second core concept)
|
|
49
|
-
|
|
50
|
-
\`\`\`ts
|
|
51
|
-
// Example of using the concept
|
|
52
|
-
\`\`\`
|
|
53
|
-
|
|
54
|
-
## Working with [Feature]
|
|
55
|
-
|
|
56
|
-
(How to use a specific feature)
|
|
57
|
-
|
|
58
|
-
\`\`\`ts
|
|
59
|
-
// Example of using the feature
|
|
60
|
-
\`\`\`
|
|
61
|
-
|
|
62
|
-
## Testing
|
|
63
|
-
|
|
64
|
-
(How to test your project)
|
|
65
|
-
|
|
66
|
-
\`\`\`ts
|
|
67
|
-
// Example of testing
|
|
68
|
-
\`\`\`
|
|
69
|
-
|
|
70
|
-
## Deployment
|
|
71
|
-
|
|
72
|
-
(How to deploy your project)
|
|
73
|
-
|
|
74
|
-
\`\`\`ts
|
|
75
|
-
// Example of deployment
|
|
76
|
-
\`\`\`
|
|
77
|
-
|
|
78
|
-
## Next Steps
|
|
79
|
-
|
|
80
|
-
(Where to go next to learn more)
|
|
81
|
-
|
|
82
|
-
> [!TIP]
|
|
83
|
-
> Make sure the examples follow a natural progression from minimal examples to more complex use cases.
|
|
84
|
-
> Keep explanations concise and focused on high-value information.
|
|
85
|
-
`,
|
|
86
|
-
});
|
|
87
|
-
}
|
package/lib/internal/index.d.ts
DELETED
package/lib/internal/index.js
DELETED