@positronic/template-new-project 0.0.76 → 0.0.78

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.
@@ -0,0 +1,73 @@
1
+ import { createBrain } from '@positronic/core';
2
+ import { components } from './components/index.js';
3
+
4
+ /**
5
+ * Project-level brain function with pre-configured components.
6
+ *
7
+ * All brains in your project should import from this file:
8
+ *
9
+ * ```typescript
10
+ * import { brain } from '../brain.js';
11
+ *
12
+ * export default brain('my-brain')
13
+ * .step('Do something', ({ state }) => ({ ...state, done: true }));
14
+ * ```
15
+ *
16
+ * ## Prompt steps with tool-calling loops
17
+ *
18
+ * Use `.prompt()` with a `loop` property to run an LLM with tools:
19
+ *
20
+ * ```typescript
21
+ * import { generatePage, waitForWebhook } from '@positronic/core';
22
+ *
23
+ * export default brain('my-brain')
24
+ * .prompt('Do Work', ({ state }) => ({
25
+ * system: 'You are a helpful assistant',
26
+ * message: `Help the user with: <%= '${state.task}' %>`,
27
+ * outputSchema: z.object({ result: z.string() }),
28
+ * loop: {
29
+ * tools: { generatePage, waitForWebhook },
30
+ * },
31
+ * }));
32
+ * ```
33
+ *
34
+ * Without `loop`, `.prompt()` makes a single LLM call for structured output.
35
+ * With `loop`, the LLM calls tools iteratively until it calls the auto-generated
36
+ * 'done' tool with data matching the outputSchema.
37
+ *
38
+ * ## Adding plugins
39
+ *
40
+ * Plugins provide services, tools, and event adapters to brains.
41
+ * Configure them in createBrain or per-brain with .withPlugin():
42
+ *
43
+ * ```typescript
44
+ * import { createBrain } from '@positronic/core';
45
+ * import { components } from './components/index.js';
46
+ * import { mem0 } from '@positronic/mem0';
47
+ *
48
+ * export const brain = createBrain({
49
+ * plugins: [mem0.setup({ apiKey: process.env.MEM0_API_KEY! })],
50
+ * components,
51
+ * });
52
+ * ```
53
+ *
54
+ * Then plugin services are available in all brain steps under the plugin name:
55
+ *
56
+ * ```typescript
57
+ * export default brain('my-brain')
58
+ * .step('Remember', async ({ mem0 }) => {
59
+ * const prefs = await mem0.search('user preferences');
60
+ * return { preferences: prefs };
61
+ * });
62
+ * ```
63
+ *
64
+ * Or declare multiple plugins upfront:
65
+ *
66
+ * ```typescript
67
+ * brain({ title: 'my-brain', plugins: { slack, mem0 } })
68
+ * .step('Go', ({ slack, mem0 }) => { ... });
69
+ * ```
70
+ */
71
+ export const brain = createBrain({
72
+ components,
73
+ });
@@ -0,0 +1,46 @@
1
+ import { brain } from '../brain.js';
2
+ import { z } from 'zod';
3
+ import { generatePage, waitForWebhook } from '@positronic/core';
4
+
5
+ /**
6
+ * A simple brain that demonstrates .prompt() with a tool-calling loop.
7
+ *
8
+ * This brain:
9
+ * 1. Uses generatePage to create a form asking for the user's name
10
+ * 2. Waits for the user to submit the form
11
+ * 3. Completes with a structured welcome message (via the 'done' tool)
12
+ * 4. The follow-up step logs the greeting, demonstrating type inference
13
+ *
14
+ * The `loop` property on `.prompt()` enables tool-calling: the LLM calls
15
+ * tools iteratively until it calls the auto-generated 'done' tool with
16
+ * data matching the outputSchema. The result is spread onto state.
17
+ *
18
+ * Run with: px brain run hello
19
+ */
20
+ export default brain('hello')
21
+ .prompt('Greet User', () => ({
22
+ system: `
23
+ You are a friendly greeter for the Positronic framework.
24
+
25
+ Your job is to welcome new users and make them feel excited about building AI workflows.
26
+
27
+ Use the generatePage tool to create a form asking for the user's name.
28
+ Once you have their name, call 'done' with a personalized greeting.
29
+ `,
30
+ message: 'Begin.',
31
+ outputSchema: z.object({
32
+ userName: z.string().describe('The name the user provided'),
33
+ greeting: z
34
+ .string()
35
+ .describe('A personalized welcome message for the user'),
36
+ }),
37
+ loop: {
38
+ tools: { generatePage, waitForWebhook },
39
+ },
40
+ }))
41
+ .step('Log Welcome', ({ state }) => {
42
+ // TypeScript knows state has userName and greeting (spread from outputSchema)
43
+ console.log('\n✨ ' + state.greeting);
44
+ console.log(' Welcome aboard, ' + state.userName + '!\n');
45
+ return state;
46
+ });
@@ -38,24 +38,21 @@ import { google } from '@ai-sdk/google';
38
38
  *
39
39
  * ## Memory
40
40
  *
41
- * To add memory (automatic conversation indexing with Mem0):
41
+ * To add semantic memory via Mem0, use the mem0 plugin in your
42
+ * src/brain.ts file:
42
43
  *
43
44
  * ```typescript
44
- * import { createMem0Provider, createMem0Adapter } from '@positronic/mem0';
45
+ * import { createBrain } from '@positronic/core';
46
+ * import { mem0 } from '@positronic/mem0';
45
47
  *
46
- * const provider = createMem0Provider({
47
- * apiKey: process.env.MEM0_API_KEY!,
48
- * });
49
- *
50
- * const memoryAdapter = createMem0Adapter({ provider });
51
- *
52
- * export const runner = new BrainRunner({
53
- * adapters: [memoryAdapter],
54
- * client: new VercelClient(google('gemini-3-pro-preview')),
55
- * resources: {},
48
+ * export const brain = createBrain({
49
+ * plugins: [mem0.setup({ apiKey: process.env.MEM0_API_KEY! })],
56
50
  * });
57
51
  * ```
58
52
  *
53
+ * Then use `mem0.search()` and `mem0.add()` in brain steps, or pass
54
+ * `mem0.tools` to a prompt loop for LLM-driven memory.
55
+ *
59
56
  * See docs/memory-guide.md for more details.
60
57
  */
61
58
  const client = new VercelClient(google('gemini-3-pro-preview'));
@@ -1,5 +1,5 @@
1
1
  import { createMockClient, runBrainTest } from './test-utils.js';
2
- import exampleBrain from '../brains/example.js';
2
+ import exampleBrain from '../src/brains/example.js';
3
3
 
4
4
  describe('example brain', () => {
5
5
  it('should complete successfully with welcome messages', async () => {
@@ -48,7 +48,6 @@ export interface BrainTestResult<TState> {
48
48
  export async function runBrainTest<
49
49
  TOptions extends object = object,
50
50
  TState extends object = object,
51
- TServices extends object = object
52
51
  >(
53
52
  brain: any,
54
53
  params?: {
@@ -56,7 +55,6 @@ export async function runBrainTest<
56
55
  initialState?: Partial<TState>;
57
56
  resources?: any;
58
57
  options?: TOptions;
59
- services?: TServices;
60
58
  }
61
59
  ): Promise<BrainTestResult<TState>> {
62
60
  const events: BrainEvent<any>[] = [];
@@ -72,8 +70,7 @@ export async function runBrainTest<
72
70
  options: params?.options,
73
71
  };
74
72
 
75
- // If brain has services, we need to apply them first
76
- const brainToRun = params?.services ? brain.withServices(params.services) : brain;
73
+ const brainToRun = brain;
77
74
 
78
75
  for await (const event of brainToRun.run(runOptions)) {
79
76
  events.push(event);
@@ -9,8 +9,10 @@
9
9
  "skipLibCheck": true,
10
10
  "forceConsistentCasingInFileNames": true,
11
11
  "outDir": "./dist",
12
- "rootDir": "./"
12
+ "rootDir": "./",
13
+ "jsx": "react-jsx",
14
+ "jsxImportSource": "@positronic/core"
13
15
  },
14
- "include": ["brains/**/*.ts", "resources.d.ts"],
16
+ "include": ["brains/**/*.ts", "brains/**/*.tsx", "resources.d.ts"],
15
17
  "exclude": ["node_modules", ".positronic"]
16
18
  }
package/template/brain.ts DELETED
@@ -1,96 +0,0 @@
1
- import { createBrain, defaultTools } from '@positronic/core';
2
- import { components } from './components/index.js';
3
-
4
- /**
5
- * Project-level brain function with pre-configured components and tools.
6
- *
7
- * All brains in your project should import from this file:
8
- *
9
- * ```typescript
10
- * import { brain } from '../brain.js';
11
- *
12
- * export default brain('my-brain')
13
- * .step('Do something', ({ state }) => ({ ...state, done: true }));
14
- * ```
15
- *
16
- * Default tools available in agent steps:
17
- * - generateUI: Generate interactive UI components
18
- * - consoleLog: Log messages for debugging
19
- * - done: Complete the agent and return a result
20
- *
21
- * Tool configuration:
22
- * - `withTools({ ... })` — replaces the default tools entirely
23
- * - `withExtraTools({ ... })` — adds tools alongside the defaults
24
- *
25
- * To add services (e.g., Slack, Gmail, database clients):
26
- *
27
- * ```typescript
28
- * import { createBrain, defaultTools } from '@positronic/core';
29
- * import { components } from './components/index.js';
30
- * import slack from './services/slack.js';
31
- * import gmail from './services/gmail.js';
32
- *
33
- * export const brain = createBrain({
34
- * services: { slack, gmail },
35
- * components,
36
- * defaultTools,
37
- * });
38
- * ```
39
- *
40
- * Then services are available in all brain steps:
41
- *
42
- * ```typescript
43
- * export default brain('notify')
44
- * .step('Send alert', ({ slack }) => {
45
- * slack.postMessage('#alerts', 'Something happened!');
46
- * return { notified: true };
47
- * });
48
- * ```
49
- *
50
- * You can also create agents directly with access to default tools:
51
- *
52
- * ```typescript
53
- * export default brain('my-agent', ({ slack, tools }) => ({
54
- * system: 'You are a helpful assistant',
55
- * prompt: 'Help the user with their request',
56
- * tools: {
57
- * ...tools, // includes generateUI, consoleLog, done
58
- * notify: {
59
- * description: 'Send a Slack notification',
60
- * inputSchema: z.object({ message: z.string() }),
61
- * execute: ({ message }) => slack.postMessage('#general', message),
62
- * },
63
- * },
64
- * }));
65
- * ```
66
- *
67
- * To add memory (long-term storage with semantic search):
68
- *
69
- * ```typescript
70
- * import { createBrain, defaultTools } from '@positronic/core';
71
- * import { createMem0Provider, createMem0Tools } from '@positronic/mem0';
72
- * import { components } from './components/index.js';
73
- *
74
- * const memory = createMem0Provider({
75
- * apiKey: process.env.MEM0_API_KEY!,
76
- * });
77
- *
78
- * export const brain = createBrain({
79
- * components,
80
- * defaultTools,
81
- * memory, // All brains now have access to memory
82
- * });
83
- *
84
- * // Memory tools (rememberFact, recallMemories) can be added to agents:
85
- * const memoryTools = createMem0Tools();
86
- * ```
87
- *
88
- * Memory is automatically scoped to the current user (via currentUser.name)
89
- * and the brain name. No need to pass userId manually.
90
- *
91
- * See docs/memory-guide.md for full details.
92
- */
93
- export const brain = createBrain({
94
- components,
95
- defaultTools,
96
- });
@@ -1,44 +0,0 @@
1
- import { brain } from '../brain.js';
2
- import { z } from 'zod';
3
-
4
- /**
5
- * A simple agent brain that demonstrates the default tools and outputSchema.
6
- *
7
- * This brain uses only a system prompt and tools - no explicit user prompt needed.
8
- * When prompt is omitted, the agent automatically starts with "Begin."
9
- *
10
- * The outputSchema ensures the agent returns structured data that gets stored
11
- * in state.welcome - making it available for subsequent steps.
12
- *
13
- * This brain:
14
- * 1. Uses generateUI to create a form asking for the user's name
15
- * 2. Waits for the user to submit the form
16
- * 3. Completes with a structured welcome message (via outputSchema)
17
- * 4. The follow-up step logs the greeting, demonstrating type inference
18
- *
19
- * Run with: px brain run hello
20
- */
21
- export default brain('hello', {
22
- system: `
23
- You are a friendly greeter for the Positronic framework.
24
-
25
- Your job is to welcome new users and make them feel excited about building AI workflows.
26
-
27
- You have access to a few different tools. Use these tools to greet the user and ask them for their name.
28
-
29
- Once you have the user's name send them a personalized greeting!
30
- `,
31
- outputSchema: {
32
- schema: z.object({
33
- userName: z.string().describe('The name the user provided'),
34
- greeting: z.string().describe('A personalized welcome message for the user'),
35
- }),
36
- name: 'welcome' as const,
37
- },
38
- })
39
- .step('Log Welcome', ({ state }) => {
40
- // TypeScript knows state.welcome has userName and greeting
41
- console.log('\n✨ ' + state.welcome.greeting);
42
- console.log(' Welcome aboard, ' + state.welcome.userName + '!\n');
43
- return state;
44
- });
File without changes
File without changes
File without changes