@simulacra-ai/core 0.0.2 → 0.0.4

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 (137) hide show
  1. package/README.md +87 -108
  2. package/dist/index.cjs +2293 -0
  3. package/dist/index.cjs.map +1 -0
  4. package/dist/index.d.cts +1631 -0
  5. package/dist/index.d.ts +1631 -10
  6. package/dist/index.js +2232 -8
  7. package/dist/index.js.map +1 -1
  8. package/package.json +10 -4
  9. package/dist/checkpoints/default-summarization-strategy.d.ts +0 -13
  10. package/dist/checkpoints/default-summarization-strategy.d.ts.map +0 -1
  11. package/dist/checkpoints/default-summarization-strategy.js +0 -63
  12. package/dist/checkpoints/default-summarization-strategy.js.map +0 -1
  13. package/dist/checkpoints/index.d.ts +0 -3
  14. package/dist/checkpoints/index.d.ts.map +0 -1
  15. package/dist/checkpoints/index.js +0 -3
  16. package/dist/checkpoints/index.js.map +0 -1
  17. package/dist/checkpoints/types.d.ts +0 -32
  18. package/dist/checkpoints/types.d.ts.map +0 -1
  19. package/dist/checkpoints/types.js +0 -2
  20. package/dist/checkpoints/types.js.map +0 -1
  21. package/dist/context-transformers/checkpoint-context-transformer.d.ts +0 -13
  22. package/dist/context-transformers/checkpoint-context-transformer.d.ts.map +0 -1
  23. package/dist/context-transformers/checkpoint-context-transformer.js +0 -32
  24. package/dist/context-transformers/checkpoint-context-transformer.js.map +0 -1
  25. package/dist/context-transformers/composite-context-transformer.d.ts +0 -31
  26. package/dist/context-transformers/composite-context-transformer.d.ts.map +0 -1
  27. package/dist/context-transformers/composite-context-transformer.js +0 -41
  28. package/dist/context-transformers/composite-context-transformer.js.map +0 -1
  29. package/dist/context-transformers/index.d.ts +0 -6
  30. package/dist/context-transformers/index.d.ts.map +0 -1
  31. package/dist/context-transformers/index.js +0 -6
  32. package/dist/context-transformers/index.js.map +0 -1
  33. package/dist/context-transformers/noop-context-transformer.d.ts +0 -24
  34. package/dist/context-transformers/noop-context-transformer.d.ts.map +0 -1
  35. package/dist/context-transformers/noop-context-transformer.js +0 -26
  36. package/dist/context-transformers/noop-context-transformer.js.map +0 -1
  37. package/dist/context-transformers/tool-context-transformer.d.ts +0 -26
  38. package/dist/context-transformers/tool-context-transformer.d.ts.map +0 -1
  39. package/dist/context-transformers/tool-context-transformer.js +0 -52
  40. package/dist/context-transformers/tool-context-transformer.js.map +0 -1
  41. package/dist/context-transformers/types.d.ts +0 -65
  42. package/dist/context-transformers/types.d.ts.map +0 -1
  43. package/dist/context-transformers/types.js +0 -2
  44. package/dist/context-transformers/types.js.map +0 -1
  45. package/dist/conversations/conversation.d.ts +0 -146
  46. package/dist/conversations/conversation.d.ts.map +0 -1
  47. package/dist/conversations/conversation.js +0 -642
  48. package/dist/conversations/conversation.js.map +0 -1
  49. package/dist/conversations/index.d.ts +0 -5
  50. package/dist/conversations/index.d.ts.map +0 -1
  51. package/dist/conversations/index.js +0 -5
  52. package/dist/conversations/index.js.map +0 -1
  53. package/dist/conversations/stream-listener.d.ts +0 -37
  54. package/dist/conversations/stream-listener.d.ts.map +0 -1
  55. package/dist/conversations/stream-listener.js +0 -68
  56. package/dist/conversations/stream-listener.js.map +0 -1
  57. package/dist/conversations/token-tracker.d.ts +0 -59
  58. package/dist/conversations/token-tracker.d.ts.map +0 -1
  59. package/dist/conversations/token-tracker.js +0 -98
  60. package/dist/conversations/token-tracker.js.map +0 -1
  61. package/dist/conversations/types.d.ts +0 -346
  62. package/dist/conversations/types.d.ts.map +0 -1
  63. package/dist/conversations/types.js +0 -2
  64. package/dist/conversations/types.js.map +0 -1
  65. package/dist/index.d.ts.map +0 -1
  66. package/dist/policies/composite-policy.d.ts +0 -29
  67. package/dist/policies/composite-policy.d.ts.map +0 -1
  68. package/dist/policies/composite-policy.js +0 -77
  69. package/dist/policies/composite-policy.js.map +0 -1
  70. package/dist/policies/default-policy.d.ts +0 -7
  71. package/dist/policies/default-policy.d.ts.map +0 -1
  72. package/dist/policies/default-policy.js +0 -14
  73. package/dist/policies/default-policy.js.map +0 -1
  74. package/dist/policies/index.d.ts +0 -8
  75. package/dist/policies/index.d.ts.map +0 -1
  76. package/dist/policies/index.js +0 -8
  77. package/dist/policies/index.js.map +0 -1
  78. package/dist/policies/noop-policy.d.ts +0 -21
  79. package/dist/policies/noop-policy.d.ts.map +0 -1
  80. package/dist/policies/noop-policy.js +0 -36
  81. package/dist/policies/noop-policy.js.map +0 -1
  82. package/dist/policies/rate-limit-policy.d.ts +0 -44
  83. package/dist/policies/rate-limit-policy.d.ts.map +0 -1
  84. package/dist/policies/rate-limit-policy.js +0 -98
  85. package/dist/policies/rate-limit-policy.js.map +0 -1
  86. package/dist/policies/retry-policy.d.ts +0 -42
  87. package/dist/policies/retry-policy.d.ts.map +0 -1
  88. package/dist/policies/retry-policy.js +0 -114
  89. package/dist/policies/retry-policy.js.map +0 -1
  90. package/dist/policies/token-limit-policy.d.ts +0 -76
  91. package/dist/policies/token-limit-policy.d.ts.map +0 -1
  92. package/dist/policies/token-limit-policy.js +0 -134
  93. package/dist/policies/token-limit-policy.js.map +0 -1
  94. package/dist/policies/types.d.ts +0 -49
  95. package/dist/policies/types.d.ts.map +0 -1
  96. package/dist/policies/types.js +0 -9
  97. package/dist/policies/types.js.map +0 -1
  98. package/dist/tools/index.d.ts +0 -2
  99. package/dist/tools/index.d.ts.map +0 -1
  100. package/dist/tools/index.js +0 -2
  101. package/dist/tools/index.js.map +0 -1
  102. package/dist/tools/types.d.ts +0 -180
  103. package/dist/tools/types.d.ts.map +0 -1
  104. package/dist/tools/types.js +0 -2
  105. package/dist/tools/types.js.map +0 -1
  106. package/dist/utils/async.d.ts +0 -125
  107. package/dist/utils/async.d.ts.map +0 -1
  108. package/dist/utils/async.js +0 -217
  109. package/dist/utils/async.js.map +0 -1
  110. package/dist/utils/index.d.ts +0 -4
  111. package/dist/utils/index.d.ts.map +0 -1
  112. package/dist/utils/index.js +0 -4
  113. package/dist/utils/index.js.map +0 -1
  114. package/dist/utils/object.d.ts +0 -80
  115. package/dist/utils/object.d.ts.map +0 -1
  116. package/dist/utils/object.js +0 -189
  117. package/dist/utils/object.js.map +0 -1
  118. package/dist/utils/types.d.ts +0 -17
  119. package/dist/utils/types.d.ts.map +0 -1
  120. package/dist/utils/types.js +0 -2
  121. package/dist/utils/types.js.map +0 -1
  122. package/dist/workflows/index.d.ts +0 -4
  123. package/dist/workflows/index.d.ts.map +0 -1
  124. package/dist/workflows/index.js +0 -4
  125. package/dist/workflows/index.js.map +0 -1
  126. package/dist/workflows/types.d.ts +0 -70
  127. package/dist/workflows/types.d.ts.map +0 -1
  128. package/dist/workflows/types.js +0 -2
  129. package/dist/workflows/types.js.map +0 -1
  130. package/dist/workflows/workflow-manager.d.ts +0 -74
  131. package/dist/workflows/workflow-manager.d.ts.map +0 -1
  132. package/dist/workflows/workflow-manager.js +0 -165
  133. package/dist/workflows/workflow-manager.js.map +0 -1
  134. package/dist/workflows/workflow.d.ts +0 -116
  135. package/dist/workflows/workflow.d.ts.map +0 -1
  136. package/dist/workflows/workflow.js +0 -351
  137. package/dist/workflows/workflow.js.map +0 -1
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Simulacra Core
2
2
 
3
- Core conversation engine, tool system, workflow management, policies, and context transformers for Simulacra.
3
+ The core package is the foundation of Simulacra. It provides a model-agnostic conversation engine that handles streaming, tool execution, retry policies, and context management.
4
4
 
5
5
  ## Installation
6
6
 
@@ -16,187 +16,166 @@ import { AnthropicProvider } from "@simulacra-ai/anthropic";
16
16
  import Anthropic from "@anthropic-ai/sdk";
17
17
 
18
18
  const provider = new AnthropicProvider(new Anthropic(), { model: MODEL_NAME });
19
- const conversation = new Conversation(provider);
19
+ using conversation = new Conversation(provider);
20
20
 
21
21
  await conversation.prompt("Hello!");
22
+
22
23
  console.log(conversation.messages);
23
24
  ```
24
25
 
25
26
  ## Conversation
26
27
 
27
- `Conversation` is a concrete class that accepts a `ModelProvider` at construction time. Provider packages (`@simulacra-ai/anthropic`, `@simulacra-ai/openai`, `@simulacra-ai/google`) supply `ModelProvider` implementations. All model-specific configuration (model name, token limits, thinking, caching) lives in the provider, not the conversation.
28
+ The `Conversation` class is the central object that the rest of the system is built on top of. It manages message history, sends prompts, and streams responses. A conversation is created with a `ModelProvider`, which handles all model-specific concerns like API calls, token limits, and thinking configuration. Providers are available for Anthropic, OpenAI, and Google, and the extensibility model makes it straightforward to add others.
29
+
30
+ The conversation itself is model-agnostic. All messages and state are represented in a normalized format, so conversations can be serialized, resumed, or switched to a different provider at any time.
28
31
 
29
32
  ```typescript
30
- const conversation = new Conversation(provider);
33
+ // create a conversation with a system prompt
34
+ using conversation = new Conversation(provider);
31
35
  conversation.system = "You are a helpful assistant.";
32
36
 
33
- const result = await conversation.prompt("Hello!");
37
+ await conversation.prompt("Hello!");
38
+
34
39
  console.log(conversation.messages);
35
40
  ```
36
41
 
37
- Properties include `id`, `state`, `system`, `toolkit`, and `messages`.
42
+ The [developer guide](DEVELOPER_GUIDE.md) includes the full API.
38
43
 
39
- Methods include `prompt(text)`, `send_message(contents)`, `cancel_response()`, `clear()`, `load(messages)`, `spawn_child(fork?, id?, system?, is_checkpoint?)`, and `checkpoint(config?)`.
44
+ ## Tools
40
45
 
41
- State transitions flow: `idle` `awaiting_response` `streaming_response` `idle` (or `stopping` `idle` on cancel, `disposed` on disposal).
46
+ Tools give an AI model the ability to take actions and retrieve information. Each tool is a class with a `get_definition` static method describing what it does and an `execute` method that runs when the model calls it. Tools are registered on the conversation via `toolkit`.
42
47
 
43
- ### Conversation Events
48
+ > Note: A `WorkflowManager` must be created to drive the tool call loop.
44
49
 
45
- Key events for streaming: `message_start`, `content_update`, `message_complete`. For tool use: `content_start`, `content_complete`. For lifecycle: `state_change`, `dispose`.
50
+ ### Tool Definition
46
51
 
47
- See the [developer guide](DEVELOPER_GUIDE.md#events) for the full event reference.
52
+ Each tool must provide a `ToolDefinition`, which declares its name, description, and parameters. The tool parameters can be primitives or complex types like arrays or objects with their own properties.
48
53
 
49
- ## Tool System
54
+ #### Parallel Behavior
50
55
 
51
- Tools are implemented via the `ToolClass` interface:
56
+ The definition can include a `parallelizable` flag that tells the workflow engine how the tool should be executed. The flag defaults to `true`, allowing the engine to execute the tool in parallel when multiple tools are called in a batch. When explicitly disabled, the engine will execute the tool on its own before continuing to other tool calls.
52
57
 
53
- ```typescript
54
- import type {
55
- ToolClass,
56
- ToolContext,
57
- ToolDefinition,
58
- ToolSuccessResult,
59
- ToolErrorResult,
60
- } from "@simulacra-ai/core";
58
+ > Note: Tool call batches are processed in order. Tools within the same batch run concurrently. If a non-parallelizable tool appears between parallelizable ones, the calls before and after it run as separate batches.
61
59
 
62
- class SearchTool {
63
- #context: ToolContext;
60
+ ### Tool Context
64
61
 
65
- static get_definition(): ToolDefinition {
66
- return {
67
- name: "search",
68
- description: "Search the web for information",
69
- parameters: [
70
- { name: "query", type: "string", required: true, description: "Search query" },
71
- { name: "max_results", type: "number", required: false, default: 5 },
72
- ],
73
- parallelizable: true,
74
- };
75
- }
62
+ The tool class constructor receives a `ToolContext` object that gives the tool access to the conversation, the active workflow, and any application-specific data passed via `context_data`.
63
+
64
+ ```typescript
65
+ import type { ToolContext, ToolDefinition, ToolSuccessResult } from "@simulacra-ai/core";
76
66
 
67
+ class WeatherTool {
77
68
  constructor(context: ToolContext) {
78
- this.#context = context;
69
+ // context includes conversation, workflow, and context_data
79
70
  }
80
71
 
81
- async execute(params: {
82
- query: string;
83
- max_results?: number;
84
- }): Promise<ToolSuccessResult | ToolErrorResult> {
85
- const results = await doSearch(params.query, params.max_results ?? 5);
86
- return { result: true, ...results };
72
+ async execute({ city }: { city: string }): Promise<ToolSuccessResult> {
73
+ // called when the model invokes this tool
74
+ return { result: true, temperature: 72, conditions: "sunny" };
87
75
  }
88
- }
89
-
90
- conversation.toolkit = [SearchTool as ToolClass];
91
- ```
92
-
93
- ### ToolDefinition
94
76
 
95
- ```typescript
96
- interface ToolDefinition {
97
- name: string;
98
- description: string;
99
- parameters: ToolParameterDefinition[];
100
- parallelizable?: boolean; // default: true
77
+ static get_definition(): ToolDefinition {
78
+ return {
79
+ name: "get_weather",
80
+ description: "Get current weather for a city",
81
+ // parameter types: string, number, boolean, object, array
82
+ parameters: [{ name: "city", type: "string", required: true }],
83
+ // parallelizable defaults to true, set false for tools with side effects
84
+ };
85
+ }
101
86
  }
102
87
  ```
103
88
 
104
- ### ToolContext
105
-
106
- Every tool instance receives `{ conversation, workflow }` at construction time, plus any application-specific data passed via `context_data`.
107
-
108
- ### Parameter Types
109
-
110
- `ToolParameterDefinition` supports: `string`, `number`, `boolean`, `object` (with nested `properties`), `array` (with `items`). String parameters support `enum` arrays. All types have `name`, `description?`, `required?`, and `default?`.
111
-
112
- ### Parallel Execution
113
-
114
- The `parallelizable` flag (default `true`) controls batching in the workflow engine:
115
-
116
- - **`true` (default)**: the workflow can batch this tool call with other parallelizable calls into `Promise.all`
117
- - **`false`**: acts as a barrier; the workflow executes this tool alone, waiting for it to complete before continuing
118
-
119
- This allows tools with side effects or ordering requirements to be marked as sequential while allowing read-only tools to run concurrently.
120
-
121
89
  ## Workflows
122
90
 
123
- `WorkflowManager` is the agentic loop. It listens for tool-use responses, executes tools, sends results back, and repeats until the model produces a final response.
91
+ The workflow engine drives the tool call loop and enables agentic behaviors. The `WorkflowManager` sits on top of the conversation object, managing workflow state and executing tools on the model's behalf, running them in parallel when possible, and feeding results back until the model produces a final response.
92
+
93
+ The workflow manager emits events throughout its lifecycle, making it possible to observe the full agentic loop.
124
94
 
125
95
  ```typescript
126
- import { WorkflowManager } from "@simulacra-ai/core";
96
+ // create a conversation and workflow manager
97
+ using manager = new WorkflowManager(conversation);
98
+
99
+ // log the final message when the workflow completes
100
+ manager.once("workflow_begin", (workflow) =>
101
+ workflow.once("workflow_end", () => {
102
+ console.log(conversation.messages.at(-1));
103
+ })
104
+ );
127
105
 
128
- const manager = new WorkflowManager(conversation);
129
106
  await conversation.prompt("Use my tools to answer this question.");
130
107
  ```
131
108
 
132
- For lower-level control, `Workflow` can be used directly — see the [developer guide](DEVELOPER_GUIDE.md#workflows).
133
-
134
- Key events: `workflow_end` (loop finished with reason `complete` | `cancel` | `error`), `workflow_update` (tool results sent), `state_change`. See the [developer guide](DEVELOPER_GUIDE.md#events) for the full event reference.
109
+ The [developer guide](DEVELOPER_GUIDE.md#events) covers the full event reference.
135
110
 
136
111
  ## Policies
137
112
 
138
- Policies wrap the LLM request with cross-cutting concerns. All policies implement `execute(cancellation_token, fn, ...args)`.
113
+ Policies control how the underlying model provider is called. They sit between the conversation and the provider, intercepting requests to add behavior like retries, rate limiting, or token budgets. Policies can be used individually or combined with `CompositePolicy`.
139
114
 
140
115
  ### RetryPolicy
141
116
 
142
117
  `RetryPolicy` retries failed requests with exponential backoff.
143
118
 
144
119
  ```typescript
145
- import { RetryPolicy } from "@simulacra-ai/core";
146
-
120
+ // create a retry policy with an optional filter
147
121
  const policy = new RetryPolicy({
148
122
  max_attempts: 3,
149
123
  initial_backoff_ms: 1000,
150
124
  backoff_factor: 2,
151
- retryable: (error) => error.error?.status === 429, // optional filter
125
+ retryable: (result) => result.error?.status === 429,
152
126
  });
153
127
  ```
154
128
 
155
- ### RateLimitPolicy
129
+ ### CompositePolicy
156
130
 
157
- `RateLimitPolicy` limits requests per time window. Pass it to the conversation constructor, then call `attach()` to subscribe to events.
131
+ `CompositePolicy` chains multiple policies together, executing them from outer to inner.
158
132
 
159
133
  ```typescript
160
- import { Conversation, RateLimitPolicy } from "@simulacra-ai/core";
134
+ // combine rate limiting with retries
135
+ const policy = new CompositePolicy(
136
+ new RateLimitPolicy({ limit: 10, period_ms: 60_000 }),
137
+ new RetryPolicy({ max_attempts: 3, initial_backoff_ms: 1000, backoff_factor: 2 }),
138
+ );
139
+ ```
161
140
 
141
+ ### RateLimitPolicy
142
+
143
+ `RateLimitPolicy` limits requests per time window.
144
+
145
+ ```typescript
146
+ // create a rate limit policy
162
147
  const policy = new RateLimitPolicy({ limit: 10, period_ms: 60_000 });
163
- const conversation = new Conversation(provider, policy);
148
+
149
+ // create a conversation with the policy
150
+ using conversation = new Conversation(provider, policy);
151
+
152
+ // attach so the policy can observe conversation events
164
153
  policy.attach(conversation);
165
154
  ```
166
155
 
167
156
  ### TokenLimitPolicy
168
157
 
169
- `TokenLimitPolicy` limits tokens per time window. Like `RateLimitPolicy`, it requires both constructor injection and `attach()`.
158
+ `TokenLimitPolicy` limits tokens per time window.
170
159
 
171
160
  ```typescript
172
- import { Conversation, TokenLimitPolicy } from "@simulacra-ai/core";
173
-
161
+ // create a token limit policy
174
162
  const policy = new TokenLimitPolicy({
175
163
  period_ms: 60_000,
176
164
  total_tokens_per_period: 120_000,
177
165
  });
178
- const conversation = new Conversation(provider, policy);
179
- policy.attach(conversation);
180
- ```
181
-
182
- ### CompositePolicy
183
166
 
184
- `CompositePolicy` chains multiple policies together.
167
+ // create a conversation with the policy
168
+ using conversation = new Conversation(provider, policy);
185
169
 
186
- ```typescript
187
- import { CompositePolicy } from "@simulacra-ai/core";
188
-
189
- const policy = new CompositePolicy(
190
- new RateLimitPolicy({ limit: 10, period_ms: 60_000 }),
191
- new RetryPolicy({ max_attempts: 3, initial_backoff_ms: 1000, backoff_factor: 2 }),
192
- );
170
+ // attach so the policy can observe conversation events
171
+ policy.attach(conversation);
193
172
  ```
194
173
 
195
174
  ## Context Transformers
196
175
 
197
- Context transformers modify messages at two points: before sending (`transform_prompt`) and after receiving (`transform_completion`).
176
+ Context transformers reshape messages on-the-fly without altering the stored conversation history. They operate at two points, before messages are sent to the model (`transform_prompt`) and after a response comes back (`transform_completion`). This enables history trimming, content filtering, or constraint enforcement without touching the original messages.
198
177
 
199
- By default, `Conversation` uses `ToolContextTransformer` and `CheckpointContextTransformer`. Pass a custom transformer to override.
178
+ By default, `Conversation` uses `ToolContextTransformer` and `CheckpointContextTransformer`. A custom transformer can be passed to override this.
200
179
 
201
180
  ### ToolContextTransformer (default)
202
181
 
@@ -216,16 +195,16 @@ Pass-through that disables all conversation-level transformations.
216
195
 
217
196
  ### Provider Context Transformers
218
197
 
219
- Model providers can bundle their own transformers via `context_transformers`. These run before conversation-level transformers and handle provider-specific quirks automatically. The conversation reads them fresh on every request, supporting runtime provider swaps.
198
+ Model providers can bundle their own transformers via `context_transformers`. These run before conversation-level transformers and handle provider-specific needs automatically.
220
199
 
221
- See the [developer guide](DEVELOPER_GUIDE.md#provider-context-transformers) for the `ProviderContextTransformer` interface.
200
+ The [developer guide](DEVELOPER_GUIDE.md#provider-context-transformers) covers the `ProviderContextTransformer` interface.
222
201
 
223
202
  ## Utilities
224
203
 
225
- - **`TokenTracker`**: attach to a conversation to accumulate input/output token counts across requests
226
- - **`CancellationTokenSource` / `CancellationToken`**: cooperative cancellation for async operations
227
- - **`sleep(ms, cancellationToken?)`**: cancellable delay
228
- - **`deep_merge(original, supplemental)`**: recursive object merge
204
+ - `TokenTracker`. Attaches to a conversation to accumulate input/output token counts across requests.
205
+ - `CancellationTokenSource` / `CancellationToken`. Cooperative cancellation for async operations.
206
+ - `sleep(ms, cancellationToken?)`. Cancellable delay.
207
+ - `deep_merge(original, supplemental)`. Recursive object merge.
229
208
 
230
209
  ## License
231
210