agentick 0.2.1 → 0.4.0

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.
Files changed (2) hide show
  1. package/README.md +433 -21
  2. package/package.json +6 -6
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # agentick
2
2
 
3
- **Build agents like you build apps.**
3
+ **The component framework for AI.**
4
4
 
5
5
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg?style=for-the-badge)](LICENSE)
6
6
  [![TypeScript](https://img.shields.io/badge/TypeScript-5.9-blue?style=for-the-badge&logo=typescript&logoColor=white)](https://www.typescriptlang.org/)
@@ -73,6 +73,72 @@ There are no prompt templates because JSX _is_ the template language. There are
73
73
 
74
74
  This is application development, not chatbot configuration.
75
75
 
76
+ ## Built-in Components
77
+
78
+ Everything in the component tree compiles to what the model sees. Components are the building blocks — compose them to construct the context window.
79
+
80
+ ### Structure
81
+
82
+ | Component | Description |
83
+ | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
84
+ | `<Timeline>` | Conversation history. Accepts a render function for full control, or renders with sensible defaults. Token budget compaction via `maxTokens`, `strategy`, `filter`, `limit`, `roles`. |
85
+ | `<Timeline.Provider>` | Context provider exposing timeline entries to descendants via `useTimelineContext()`. |
86
+ | `<Timeline.Messages>` | Renders messages from `Timeline.Provider` context. Optional `renderEntry` prop for custom rendering. |
87
+ | `<Section>` | Structured context block injected every tick. `audience` controls visibility: `"model"`, `"user"`, or `"all"`. |
88
+ | `<Model>` | Model configuration. Pass `engine` prop, or use adapter-specific components like `<OpenAIModel>` or `<GoogleModel>`. |
89
+
90
+ ### Messages
91
+
92
+ | Component | Description |
93
+ | -------------- | ---------------------------------------------------------------------------------------------------------------------------- |
94
+ | `<System>` | System/instruction message. |
95
+ | `<User>` | User message. |
96
+ | `<Assistant>` | Assistant message. |
97
+ | `<Message>` | Generic message — takes `role` prop. The primitive underlying all role-specific components. |
98
+ | `<ToolResult>` | Tool execution result. Requires `toolCallId`. |
99
+ | `<Event>` | Persisted application event. Use for structured logging that survives in the timeline. |
100
+ | `<Ephemeral>` | Non-persisted context. Visible during compilation but not saved to history. `position`: `"start"`, `"before-user"`, `"end"`. |
101
+ | `<Grounding>` | Semantic wrapper for grounding context (ephemeral). `audience`: `"model"`, `"user"`, `"both"`. |
102
+
103
+ ### Event Blocks
104
+
105
+ Use inside `<Event>` messages for structured event content:
106
+
107
+ | Component | Description |
108
+ | --------------- | ------------------------------------------------------------------------ |
109
+ | `<UserAction>` | User action block. Props: `action`, `actor?`, `target?`, `details?`. |
110
+ | `<SystemEvent>` | System event block. Props: `event`, `source?`, `data?`. |
111
+ | `<StateChange>` | State change block. Props: `entity`, `field?`, `from`, `to`, `trigger?`. |
112
+
113
+ ### Semantic Formatting
114
+
115
+ Compile to renderer-appropriate output (markdown, XML, etc.):
116
+
117
+ | Component | Description |
118
+ | ---------------------- | ------------------------------------------------------------------------------------------- |
119
+ | `<H1>`, `<H2>`, `<H3>` | Heading levels 1–3. |
120
+ | `<Header level={n}>` | Generic heading (levels 1–6). |
121
+ | `<Paragraph>` | Text paragraph block. |
122
+ | `<List>` | List container. `ordered` for numbered, `task` for checkboxes. `title` for a heading. |
123
+ | `<ListItem>` | List item. `checked` prop for task lists. |
124
+ | `<Table>` | Table. `headers`/`rows` props for data, or `<Row>`/`<Column>` children for JSX composition. |
125
+ | `<Row>` | Table row. `header` prop for header rows. |
126
+ | `<Column>` | Table column. `align`: `"left"`, `"center"`, `"right"`. |
127
+
128
+ ### Content Blocks
129
+
130
+ Typed content for composing rich message content:
131
+
132
+ | Component | Description |
133
+ | ------------ | ------------------------------------------------------------------------------------------- |
134
+ | `<Text>` | Text content. Children or `text` prop. Supports inline formatting: `<b>`, `<em>`, `<code>`. |
135
+ | `<Image>` | Image. `source: MediaSource` (URL or base64). |
136
+ | `<Document>` | Document attachment. `source: MediaSource`, `title?`. |
137
+ | `<Audio>` | Audio content. `source: MediaSource`, `transcript?`. |
138
+ | `<Video>` | Video content. `source: MediaSource`, `transcript?`. |
139
+ | `<Code>` | Code block. `language` prop (typescript, python, etc.). |
140
+ | `<Json>` | JSON data block. `data` prop for objects, or `text`/children for raw JSON strings. |
141
+
76
142
  ## The Context Is Yours
77
143
 
78
144
  The core insight: **only what you render gets sent to the model.** `<Timeline>` isn't a magic black box — it accepts a render function, and you decide exactly how every message appears in the context window. Skip a message? The model never sees it. Rewrite it? That's what the model reads.
@@ -229,9 +295,76 @@ function AgentWithContext({ userId }: { userId: string }) {
229
295
 
230
296
  `<Section>` injects structured context that the model sees every tick — live data, computed state, whatever you need. The `audience` prop controls visibility (`"model"`, `"user"`, or `"all"`).
231
297
 
232
- ## Hooks Control the Loop
298
+ ## Hooks
299
+
300
+ Hooks are real React hooks — `useState`, `useEffect`, `useMemo` — plus lifecycle hooks that fire at each phase of the agent execution loop.
301
+
302
+ ### All Hooks
303
+
304
+ #### Lifecycle
305
+
306
+ | Hook | Description |
307
+ | --------------------- | -------------------------------------------------------------------------------------------------- |
308
+ | `useOnMount(cb)` | Run once when component first mounts. |
309
+ | `useOnUnmount(cb)` | Run once when component unmounts. |
310
+ | `useOnTickStart(cb)` | Run at start of each tick (tick 2+). Receives `(tickState, ctx)`. |
311
+ | `useOnTickEnd(cb)` | Run at end of each tick. Receives `(result, ctx)`. Return `false` or call `result.stop()` to halt. |
312
+ | `useAfterCompile(cb)` | Run after compilation completes. Receives `(compiled, ctx)`. |
313
+ | `useContinuation(cb)` | Control whether execution continues. Sugar for `useOnTickEnd`. |
314
+
315
+ #### State & Signals
233
316
 
234
- Hooks are real React hooks — `useState`, `useEffect`, `useMemo` — plus lifecycle hooks that fire at each phase of execution.
317
+ | Hook | Description |
318
+ | ---------------------------- | --------------------------------------------------------------------------------------------------------------- |
319
+ | `useSignal(initial)` | Reactive signal. `.set()`, `.update()`, `.subscribe()`. Reads outside render, triggers reconciliation on write. |
320
+ | `useComputed(fn, deps)` | Computed signal. Auto-updates when dependencies change. |
321
+ | `useComState(key, default?)` | Reactive COM state. Bidirectional sync with the context object model. |
322
+
323
+ Standalone signal factories (no hook rules — use anywhere):
324
+
325
+ | Function | Description |
326
+ | ----------------- | ------------------------------------------------------------------------------------------ |
327
+ | `signal(initial)` | Create a signal. |
328
+ | `computed(fn)` | Create a computed signal. |
329
+ | `effect(fn)` | Run side effect with automatic dependency tracking. Returns `EffectRef` with `.dispose()`. |
330
+ | `batch(fn)` | Batch signal updates — effects fire once after all updates. |
331
+ | `untracked(fn)` | Read signals without tracking as dependencies. |
332
+
333
+ #### Data
334
+
335
+ | Hook | Description |
336
+ | ------------------------------ | ------------------------------------------------------------------------------------------------------------- |
337
+ | `useData(key, fetcher, deps?)` | Async data fetch with resolve-then-render. Throws promise on first render, returns cached value on re-render. |
338
+ | `useInvalidateData()` | Returns `(pattern: string \| RegExp) => void` to invalidate cached data. |
339
+
340
+ #### Knobs (Model-Visible State)
341
+
342
+ Knobs are reactive values the model can see _and set_ via tool calls:
343
+
344
+ | API | Description |
345
+ | --------------------------- | ------------------------------------------------------------------------------ |
346
+ | `knob(default, opts?)` | Create a knob descriptor at config level. |
347
+ | `useKnob(name, descriptor)` | Hook returning `[resolvedValue, setValue]`. |
348
+ | `<Knobs />` | Component that renders all knobs as a `<Section>` + registers `set_knob` tool. |
349
+ | `<Knobs.Provider>` | Context provider for custom knob rendering. |
350
+ | `<Knobs.Controls>` | Renders knob controls from `Knobs.Provider` context. |
351
+ | `isKnob(value)` | Type guard for knob descriptors. |
352
+
353
+ #### Context & Environment
354
+
355
+ | Hook | Description |
356
+ | -------------------------- | ------------------------------------------------------------------ |
357
+ | `useCom()` | Access the COM (context object model) — state, timeline, channels. |
358
+ | `useTickState()` | Current tick state: `{tick, previous, queuedMessages}`. |
359
+ | `useRuntimeStore()` | Runtime data store (hooks, knobs, lifecycle callbacks). |
360
+ | `useFormatter()` | Access message formatter context. |
361
+ | `useContextInfo()` | Real-time context utilization: token counts, utilization %. |
362
+ | `useTimelineContext()` | Timeline context (requires `Timeline.Provider` ancestor). |
363
+ | `useConversationHistory()` | Full conversation history from COM (no provider needed). |
364
+
365
+ #### React (re-exported)
366
+
367
+ All standard React hooks work in agent components: `useState`, `useEffect`, `useReducer`, `useMemo`, `useCallback`, `useRef`.
235
368
 
236
369
  ### Stop Conditions
237
370
 
@@ -356,6 +489,23 @@ const output = await Search.run({ query: "test" });
356
489
  const handle = await model.generate(input);
357
490
  ```
358
491
 
492
+ ### Tool Types
493
+
494
+ Tools have execution types and intents that control routing and behavior:
495
+
496
+ | Execution Type | Description |
497
+ | -------------- | ---------------------------------------- |
498
+ | `SERVER` | Executes on server (default). |
499
+ | `CLIENT` | Executes in browser. |
500
+ | `MCP` | Routed to Model Context Protocol server. |
501
+ | `PROVIDER` | Handled by model provider natively. |
502
+
503
+ | Intent | Description |
504
+ | --------- | -------------------------- |
505
+ | `COMPUTE` | Returns data (default). |
506
+ | `ACTION` | Performs side effects. |
507
+ | `RENDER` | Produces UI/visualization. |
508
+
359
509
  ## Sessions
360
510
 
361
511
  ```tsx
@@ -375,9 +525,23 @@ for await (const event of session.send({ messages: [msg("Another one")] })) {
375
525
  if (event.type === "content_delta") process.stdout.write(event.delta);
376
526
  }
377
527
 
378
- session.close();
528
+ await session.close();
529
+ ```
530
+
531
+ Sessions are long-lived conversation contexts. Each `send()` creates an **execution** (one user message → model response cycle). Each model API call within an execution is a **tick**. Multi-tick executions happen automatically with tool use.
532
+
533
+ ```
534
+ Session
535
+ ├── Execution 1 (user: "Hello")
536
+ │ └── Tick 1 → model response
537
+ ├── Execution 2 (user: "Use calculator")
538
+ │ ├── Tick 1 → tool_use (calculator)
539
+ │ └── Tick 2 → final response
540
+ └── Execution 3 ...
379
541
  ```
380
542
 
543
+ Session states: `idle` → `running` → `idle` (or `closed`).
544
+
381
545
  ### Dynamic Model Selection
382
546
 
383
547
  Models are JSX components — conditionally render them:
@@ -397,25 +561,237 @@ function AdaptiveAgent({ task }: { task: string }) {
397
561
  }
398
562
  ```
399
563
 
564
+ ## Execution Runners
565
+
566
+ The context window is JSX. But what _consumes_ that context — and how tool calls _execute_ — is pluggable.
567
+
568
+ An `ExecutionRunner` is a swappable backend that sits between the compiled context and execution. It transforms what the model sees, intercepts how tools run, and manages its own lifecycle state. Your agent code doesn't change — the runner changes the execution model underneath it.
569
+
570
+ ```tsx
571
+ import { type ExecutionRunner } from "@agentick/core";
572
+
573
+ const repl: ExecutionRunner = {
574
+ name: "repl",
575
+
576
+ // The model sees command descriptions instead of tool schemas
577
+ prepareModelInput(compiled, tools) {
578
+ return { ...compiled, tools: [executeTool] };
579
+ },
580
+
581
+ // "execute" calls go to a sandbox; everything else runs normally
582
+ async executeToolCall(call, tool, next) {
583
+ if (call.name === "execute") return sandbox.run(call.input.code);
584
+ return next();
585
+ },
586
+
587
+ onSessionInit(session) {
588
+ sandbox.create(session.id);
589
+ },
590
+ onDestroy(session) {
591
+ sandbox.destroy(session.id);
592
+ },
593
+ };
594
+
595
+ const app = createApp(Agent, { model, runner: repl });
596
+ ```
597
+
598
+ Same agent, same JSX, different execution model. Build once — run against standard tool_use in production, a sandboxed REPL for code execution, a human-approval gateway for sensitive operations.
599
+
600
+ All hooks are optional. Without a runner, standard model → tool_use behavior applies. Runners are inherited by spawned child sessions — override per-child via `SpawnOptions`:
601
+
602
+ ```tsx
603
+ await session.spawn(CodeAgent, { messages }, { runner: replEnv });
604
+ ```
605
+
606
+ ## Testing
607
+
608
+ Agentick includes a full testing toolkit. Render agents, compile context, mock models, and assert on behavior — all without making real API calls.
609
+
610
+ ### `renderAgent` — Full Execution
611
+
612
+ Render an agent in a test environment with a mock model:
613
+
614
+ ```tsx
615
+ import { renderAgent, cleanup } from "@agentick/core/testing";
616
+ import { afterEach, test, expect } from "vitest";
617
+
618
+ afterEach(cleanup);
619
+
620
+ test("research agent searches then summarizes", async () => {
621
+ const { send, model } = renderAgent(<ResearchAgent />);
622
+
623
+ // Queue model responses
624
+ model.addResponse({ text: "", toolCalls: [{ name: "search", input: { query: "quantum" } }] });
625
+ model.addResponse({ text: "Here's a summary of quantum computing..." });
626
+
627
+ const result = await send("What's new in quantum computing?");
628
+
629
+ expect(result.response).toContain("summary");
630
+ expect(model.calls).toHaveLength(2); // two ticks
631
+ });
632
+ ```
633
+
634
+ ### `compileAgent` — Inspect Context
635
+
636
+ Compile an agent without executing to inspect what the model would see:
637
+
638
+ ```tsx
639
+ test("agent includes user context in system prompt", async () => {
640
+ const { sections, tools } = compileAgent(<AgentWithContext userId="user-123" />);
641
+
642
+ expect(sections).toContainEqual(expect.objectContaining({ id: "user-context" }));
643
+ expect(tools.map((t) => t.name)).toContain("create_ticket");
644
+ });
645
+ ```
646
+
647
+ ### Test Adapter
648
+
649
+ Create a mock model adapter for fine-grained control over streaming:
650
+
651
+ ```tsx
652
+ import { createTestAdapter } from "@agentick/core/testing";
653
+
654
+ const adapter = createTestAdapter();
655
+
656
+ // Simulate streaming chunks
657
+ adapter.stream([
658
+ { type: "text", text: "Hello " },
659
+ { type: "text", text: "world!" },
660
+ { type: "finish", stopReason: "end_turn" },
661
+ ]);
662
+ ```
663
+
664
+ ### Mocks & Helpers
665
+
666
+ | Utility | Description |
667
+ | ----------------------------- | ----------------------------------------------------- |
668
+ | `createMockApp()` | Mock app for client/transport tests. |
669
+ | `createMockSession()` | Mock session with send/close/abort. |
670
+ | `createMockExecutionHandle()` | Mock execution handle (async iterable + result). |
671
+ | `createTestRunner()` | Mock execution runner with call tracking. |
672
+ | `createMockCom()` | Mock COM for hook tests. |
673
+ | `createMockTickState()` | Mock tick state. |
674
+ | `createMockTickResult()` | Mock tick result for `useOnTickEnd` tests. |
675
+ | `makeTimelineEntry()` | Create timeline entries for assertions. |
676
+ | `act(fn)` / `actSync(fn)` | Execute in act context. |
677
+ | `waitFor(fn)` | Poll until condition is met. |
678
+ | `flushMicrotasks()` | Flush pending microtasks. |
679
+ | `createDeferred()` | Create deferred promise with external resolve/reject. |
680
+
681
+ ## Terminal UI
682
+
683
+ `@agentick/tui` provides an Ink-based terminal interface for chatting with agents — locally or over the network.
684
+
685
+ ```bash
686
+ npm install @agentick/tui
687
+ ```
688
+
689
+ ### Local — In-Process
690
+
691
+ Connect directly to an app. No server needed:
692
+
693
+ ```tsx
694
+ import { createTUI } from "@agentick/tui";
695
+ import { createApp, System, Timeline } from "@agentick/core";
696
+ import { openai } from "@agentick/openai";
697
+
698
+ function Agent() {
699
+ return (
700
+ <>
701
+ <System>You are helpful.</System>
702
+ <Timeline />
703
+ </>
704
+ );
705
+ }
706
+
707
+ const app = createApp(Agent, { model: openai({ model: "gpt-4o" }) });
708
+ const tui = createTUI({ app });
709
+ await tui.start();
710
+ ```
711
+
712
+ ### Remote — Over SSE
713
+
714
+ Connect to a running gateway or express server:
715
+
716
+ ```tsx
717
+ const tui = createTUI({ url: "http://localhost:3000/api" });
718
+ await tui.start();
719
+ ```
720
+
721
+ ### CLI
722
+
723
+ ```bash
724
+ # Run a local agent file
725
+ agentick-tui --app ./my-agent.tsx
726
+
727
+ # Connect to a remote server
728
+ agentick-tui --url http://localhost:3000/api
729
+
730
+ # Custom export name
731
+ agentick-tui --app ./agents.tsx --export SalesAgent
732
+
733
+ # Custom UI component
734
+ agentick-tui --app ./my-agent.tsx --ui ./dashboard.tsx
735
+ ```
736
+
737
+ ### Pluggable UI
738
+
739
+ The TUI ships with a default `Chat` component, but you can provide your own:
740
+
741
+ ```tsx
742
+ import { createTUI, type TUIComponent } from "@agentick/tui";
743
+ import { useSession, useStreamingText } from "@agentick/react";
744
+
745
+ const Dashboard: TUIComponent = ({ sessionId }) => {
746
+ const { send } = useSession({ sessionId });
747
+ const { text, isStreaming } = useStreamingText({ sessionId });
748
+ // ... your Ink components
749
+ };
750
+
751
+ const tui = createTUI({ app, ui: Dashboard });
752
+ ```
753
+
754
+ All building-block components are exported for custom UIs: `MessageList`, `StreamingMessage`, `ToolCallIndicator`, `ToolConfirmationPrompt`, `InputBar`, `ErrorDisplay`.
755
+
756
+ ## React Hooks for UIs
757
+
758
+ `@agentick/react` provides hooks for building browser or terminal UIs over agent sessions. These are pure React — no browser APIs — so they work in both React DOM and Ink.
759
+
760
+ ```bash
761
+ npm install @agentick/react
762
+ ```
763
+
764
+ | Hook | Description |
765
+ | ------------------------- | -------------------------------------------------------------- |
766
+ | `useClient()` | Access the Agentick client from context. |
767
+ | `useConnection()` | SSE connection state: `{state, isConnected, isConnecting}`. |
768
+ | `useSession(opts?)` | Session accessor: `{send, abort, close, subscribe, accessor}`. |
769
+ | `useEvents(opts?)` | Subscribe to stream events. Returns `{event, clear()}`. |
770
+ | `useStreamingText(opts?)` | Accumulated streaming text: `{text, isStreaming, clear()}`. |
771
+ | `useContextInfo(opts?)` | Context utilization info (token counts, %). |
772
+
773
+ Wrap your app in `<AgentickProvider client={client}>` to provide the client context.
774
+
400
775
  ## Packages
401
776
 
402
- | Package | Description |
403
- | --------------------- | ------------------------------------------------------------ |
404
- | `@agentick/core` | Reconciler, components, hooks, tools, sessions |
405
- | `@agentick/kernel` | Execution kernel — procedures, context, middleware, channels |
406
- | `@agentick/shared` | Platform-independent types and utilities |
407
- | `@agentick/openai` | OpenAI adapter (GPT-4o, o1, etc.) |
408
- | `@agentick/google` | Google AI adapter (Gemini) |
409
- | `@agentick/ai-sdk` | Vercel AI SDK adapter (any provider) |
410
- | `@agentick/gateway` | Multi-app server with auth, routing, and channels |
411
- | `@agentick/express` | Express.js integration |
412
- | `@agentick/nestjs` | NestJS integration |
413
- | `@agentick/client` | TypeScript client for gateway connections |
414
- | `@agentick/react` | React hooks for building UIs over sessions |
415
- | `@agentick/devtools` | Fiber tree inspector, tick scrubber, token tracker |
416
- | `@agentick/cli` | CLI for running agents |
417
- | `@agentick/server` | Server utilities |
418
- | `@agentick/socket.io` | Socket.IO transport |
777
+ | Package | Description |
778
+ | --------------------- | ----------------------------------------------------------------- |
779
+ | `@agentick/core` | Reconciler, components, hooks, tools, sessions, testing utilities |
780
+ | `@agentick/kernel` | Execution kernel — procedures, context, middleware, channels |
781
+ | `@agentick/shared` | Platform-independent types and utilities |
782
+ | `@agentick/openai` | OpenAI adapter (GPT-4o, o1, etc.) |
783
+ | `@agentick/google` | Google AI adapter (Gemini) |
784
+ | `@agentick/ai-sdk` | Vercel AI SDK adapter (any provider) |
785
+ | `@agentick/gateway` | Multi-app server with auth, routing, and channels |
786
+ | `@agentick/express` | Express.js integration |
787
+ | `@agentick/nestjs` | NestJS integration |
788
+ | `@agentick/client` | TypeScript client for gateway connections |
789
+ | `@agentick/react` | React hooks for building UIs over sessions |
790
+ | `@agentick/tui` | Terminal UI Ink-based chat interface for local or remote agents |
791
+ | `@agentick/devtools` | Fiber tree inspector, tick scrubber, token tracker |
792
+ | `@agentick/cli` | CLI for running agents |
793
+ | `@agentick/server` | Server utilities |
794
+ | `@agentick/socket.io` | Socket.IO transport |
419
795
 
420
796
  ## Adapters
421
797
 
@@ -431,14 +807,50 @@ const gemini = google({ model: "gemini-2.5-pro" });
431
807
  const sdk = aiSdk({ model: yourAiSdkModel });
432
808
  ```
433
809
 
810
+ Adapters return a `ModelClass` — callable _and_ a JSX component:
811
+
812
+ ```tsx
813
+ // As JSX — configure model in the component tree
814
+ <gpt temperature={0.2} maxTokens={1000} />;
815
+
816
+ // As function — call programmatically
817
+ const handle = await gpt.generate(input);
818
+ ```
819
+
434
820
  ## DevTools
435
821
 
822
+ ### Agentick DevTools
823
+
436
824
  ```tsx
437
825
  const app = createApp(Agent, { model, devTools: true });
438
826
  ```
439
827
 
440
828
  Fiber tree inspector, tick-by-tick scrubber, token usage tracking, real-time execution timeline. Record full sessions for replay with `session({ recording: 'full' })`.
441
829
 
830
+ ### React DevTools
831
+
832
+ Agentick is built on `react-reconciler` — the same foundation as React DOM and React Native. This means [React DevTools](https://github.com/facebook/react/tree/main/packages/react-devtools) works out of the box. You can inspect the component tree that compiles into the model's context window, live.
833
+
834
+ ```sh
835
+ npm install --save-dev react-devtools-core
836
+ ```
837
+
838
+ ```tsx
839
+ import { enableReactDevTools } from "@agentick/core";
840
+
841
+ enableReactDevTools(); // connects to standalone DevTools on port 8097
842
+ ```
843
+
844
+ ```sh
845
+ # Terminal 1: start React DevTools
846
+ npx react-devtools
847
+
848
+ # Terminal 2: run your agent
849
+ node my-agent.js
850
+ ```
851
+
852
+ You'll see the full component tree — `<System>`, `<Timeline>`, `<Section>`, your custom components, tools — in the same inspector you use for web and mobile apps. Inspect props, watch state changes between ticks, and see exactly what compiles into the context window.
853
+
442
854
  ## Gateway
443
855
 
444
856
  Deploy multiple apps behind a single server with auth, routing, and channel adapters:
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "agentick",
3
- "version": "0.2.1",
4
- "description": "Build agents like you build apps.",
3
+ "version": "0.4.0",
4
+ "description": "The component framework for AI.",
5
5
  "keywords": [
6
6
  "agent",
7
7
  "ai",
@@ -9,7 +9,7 @@
9
9
  "jsx",
10
10
  "react"
11
11
  ],
12
- "license": "ISC",
12
+ "license": "MIT",
13
13
  "author": "Ryan Lindgren",
14
14
  "repository": {
15
15
  "type": "git",
@@ -31,9 +31,9 @@
31
31
  "access": "public"
32
32
  },
33
33
  "dependencies": {
34
- "@agentick/agent": "0.2.1",
35
- "@agentick/guardrails": "0.2.1",
36
- "@agentick/core": "0.2.1"
34
+ "@agentick/agent": "0.4.0",
35
+ "@agentick/core": "0.4.0",
36
+ "@agentick/guardrails": "0.4.0"
37
37
  },
38
38
  "scripts": {
39
39
  "build": "tsc -p tsconfig.build.json",