@symplek/core 0.0.0-stage → 1.0.0-beta.2

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 (94) hide show
  1. package/CHANGELOG.md +89 -0
  2. package/LICENSE +21 -0
  3. package/README.md +240 -2
  4. package/dist/agent/index.cjs +20 -0
  5. package/dist/agent/index.d.cts +3 -0
  6. package/dist/agent/index.d.ts +3 -0
  7. package/dist/agent/index.js +20 -0
  8. package/dist/anthropic-EIPGZSEZ.cjs +488 -0
  9. package/dist/anthropic-Y3KNNYIL.js +488 -0
  10. package/dist/change-kernel/index.cjs +854 -0
  11. package/dist/change-kernel/index.d.cts +314 -0
  12. package/dist/change-kernel/index.d.ts +314 -0
  13. package/dist/change-kernel/index.js +854 -0
  14. package/dist/chunk-2QWRQT2P.cjs +1490 -0
  15. package/dist/chunk-3VUBEDWJ.cjs +77 -0
  16. package/dist/chunk-6L5QP3YO.js +0 -0
  17. package/dist/chunk-7Q4XLFSV.cjs +747 -0
  18. package/dist/chunk-7RKKIF7Q.cjs +1 -0
  19. package/dist/chunk-ARU4KP75.cjs +1 -0
  20. package/dist/chunk-ESDJ5FU2.js +0 -0
  21. package/dist/chunk-EUQOAMNX.js +2567 -0
  22. package/dist/chunk-IAR46ZBO.js +77 -0
  23. package/dist/chunk-IJP2U2XS.cjs +176 -0
  24. package/dist/chunk-JD7V6O63.cjs +159 -0
  25. package/dist/chunk-KMPTGYQG.cjs +436 -0
  26. package/dist/chunk-KZENMWCH.cjs +164 -0
  27. package/dist/chunk-LJVZULOA.js +47 -0
  28. package/dist/chunk-LMWBMLRZ.js +391 -0
  29. package/dist/chunk-MTQ2NXB4.js +74 -0
  30. package/dist/chunk-NRB3APQX.js +747 -0
  31. package/dist/chunk-OFIED6NN.cjs +1217 -0
  32. package/dist/chunk-R7OYLOLD.cjs +391 -0
  33. package/dist/chunk-RSOC4W4V.js +1217 -0
  34. package/dist/chunk-TY3SIHCX.js +1490 -0
  35. package/dist/chunk-TY62ZM33.js +164 -0
  36. package/dist/chunk-UJEIK56B.js +436 -0
  37. package/dist/chunk-VCWOKU3U.js +159 -0
  38. package/dist/chunk-VJATZB4Z.cjs +74 -0
  39. package/dist/chunk-XSB52MHA.cjs +47 -0
  40. package/dist/chunk-XSO3HG4U.js +176 -0
  41. package/dist/chunk-YJYOAWFP.cjs +2567 -0
  42. package/dist/coherence/index.cjs +46 -0
  43. package/dist/coherence/index.d.cts +304 -0
  44. package/dist/coherence/index.d.ts +304 -0
  45. package/dist/coherence/index.js +46 -0
  46. package/dist/confidence/index.cjs +66 -0
  47. package/dist/confidence/index.d.cts +677 -0
  48. package/dist/confidence/index.d.ts +677 -0
  49. package/dist/confidence/index.js +66 -0
  50. package/dist/context-BsyelUbJ.d.cts +305 -0
  51. package/dist/context-CRhFU7Ca.d.ts +305 -0
  52. package/dist/google-4FGC44G5.js +245 -0
  53. package/dist/google-DAPEH6GO.cjs +245 -0
  54. package/dist/index-BiYShIGN.d.ts +132 -0
  55. package/dist/index-idgX6aVg.d.cts +132 -0
  56. package/dist/index.cjs +1059 -0
  57. package/dist/index.d.cts +1281 -0
  58. package/dist/index.d.ts +1281 -0
  59. package/dist/index.js +1059 -0
  60. package/dist/interview/index.cjs +30 -0
  61. package/dist/interview/index.d.cts +108 -0
  62. package/dist/interview/index.d.ts +108 -0
  63. package/dist/interview/index.js +30 -0
  64. package/dist/openai-ST4Y5X2R.cjs +330 -0
  65. package/dist/openai-WL4S52QW.js +330 -0
  66. package/dist/operators/index.cjs +37 -0
  67. package/dist/operators/index.d.cts +207 -0
  68. package/dist/operators/index.d.ts +207 -0
  69. package/dist/operators/index.js +37 -0
  70. package/dist/rehearsal/index.cjs +97 -0
  71. package/dist/rehearsal/index.d.cts +230 -0
  72. package/dist/rehearsal/index.d.ts +230 -0
  73. package/dist/rehearsal/index.js +97 -0
  74. package/dist/runStandalone-Dql9RPr8.d.cts +3866 -0
  75. package/dist/runStandalone-Dql9RPr8.d.ts +3866 -0
  76. package/dist/server.cjs +634 -0
  77. package/dist/server.d.cts +310 -0
  78. package/dist/server.d.ts +310 -0
  79. package/dist/server.js +634 -0
  80. package/dist/solo-DfGrbLCJ.d.cts +98 -0
  81. package/dist/solo-TFTcy1_6.d.ts +98 -0
  82. package/dist/store/index.cjs +296 -0
  83. package/dist/store/index.d.cts +174 -0
  84. package/dist/store/index.d.ts +174 -0
  85. package/dist/store/index.js +296 -0
  86. package/dist/testing-Bl5CE3EB.d.ts +1180 -0
  87. package/dist/testing-DZMDQudY.d.cts +1180 -0
  88. package/dist/trust-CgK6sega.d.cts +93 -0
  89. package/dist/trust-IbNLKcTW.d.ts +93 -0
  90. package/dist/uncertainty/index.cjs +37 -0
  91. package/dist/uncertainty/index.d.cts +111 -0
  92. package/dist/uncertainty/index.d.ts +111 -0
  93. package/dist/uncertainty/index.js +37 -0
  94. package/package.json +215 -3
package/CHANGELOG.md ADDED
@@ -0,0 +1,89 @@
1
+ # Changelog
2
+
3
+ ## 1.0.0-beta.2
4
+
5
+ ### Patch Changes
6
+
7
+ - 91ca43f: First public beta. Everything since the internal `1.0.0-beta.1` milestone, which was never published.
8
+
9
+ **@symplek/core, added**
10
+ - OpenTelemetry export: `configureOpenTelemetry()`, `exportTraces()` and `shutdownOpenTelemetry()` emit spans with `gen_ai.*` attributes. The OTel packages are optional peer dependencies.
11
+ - `.reflect()` operator for critique and improvement loops driven by agents you supply.
12
+ - Idempotency keys on `AgentUnit.run()` with an injectable `IdempotencyStore`. Concurrent runs on the same key execute once. If the work succeeds but the store write fails, the run raises `IdempotencyStoreWriteError` instead of inviting a retry. At-most-once holds while the store is available.
13
+ - Subpath exports: `@symplek/core/confidence`, `/coherence`, `/interview`, `/change-kernel`, `/operators` and `/rehearsal`.
14
+ - `converge` accepts `mergeStrategy: "last" | "reduce"`.
15
+ - Provider SDKs load on first use, so `@symplek/core/server` only needs the SDK for the provider you call. A missing SDK raises a `PROVIDER_ERROR` naming the package to install.
16
+ - Zod 4 is supported alongside Zod 3. The `zod` peer range is `^3.25.28 || ^4.0.0`.
17
+
18
+ **@symplek/core, fixed**
19
+ - `Symplek.configure()` now takes effect (it was a silent no-op). It falls back to the provider's conventional environment variable when no `apiKey` is given, never pairs a key with a provider it was not supplied for, and a newer call supersedes an older bootstrap still in flight.
20
+ - A provider API key in the environment is enough to run. `ai()`, `Symplek()`, `stream()` and agents (`Symplek.agent()`) load the matching provider on first use with no `configure()` call. Reaching for a second provider by id does not change the default one.
21
+ - `ai(prompt, { schema })` tells the model the schema. The JSON Schema for the Zod type is sent with the request, where before the model was asked for JSON and never shown the fields.
22
+ - Schemas with arrays, enums, unions, literals and nullable fields are converted in full. The previous converter dropped every field that was not a string, number, boolean or object.
23
+ - The Anthropic adapter returns the answer when the reply begins with a thinking block, which is what current Claude models send. It used to return an empty string. Its default output cap is 16000 tokens, and a refusal is reported as a `content_filter` finish.
24
+ - A refused request, or one that spends its output limit before any answer is written, throws `PROVIDER_ERROR` from `ai()`, `Symplek()`, `stream()` and agents (`Symplek.agent()`). It used to come back as an empty string that read as a reply.
25
+ - Default models are current: `claude-opus-5-5`, `claude-sonnet-5-5` and `claude-haiku-5-5` for Anthropic, `gemini-3.8-flash` and `gemini-3.5-flash-lite` for Google, `gpt-4o` and `gpt-4o-mini` for OpenAI. The previous Google defaults and the Anthropic fast default were ids the providers no longer serve.
26
+ - `require("@symplek/core")` and `require("@symplek/core/server")` share one copy of the code. Each CommonJS entry point used to carry its own, so a provider configured through one was invisible to the other.
27
+ - Each module format has its own type declarations, so a CommonJS project under `node16` resolution type-checks.
28
+ - Coordination operators no longer print the legacy-mode deprecation warning for callers who never chose legacy mode.
29
+ - API keys are removed from error messages and from the attached `cause`, in every occurrence.
30
+ - Default model selection follows the provider actually in use, so Anthropic and Google callers no longer receive OpenAI model ids.
31
+ - Anthropic streaming reports accurate token totals.
32
+ - Options that were accepted and ignored now apply: `timeout` and `retry` when a schema is given, `provider`, `system` and `temperature` on `Symplek.agent`, `SymplekOptions.confidence`, and `StreamOptions.signal`.
33
+ - Consensus cancels losing voters when a vote times out and does not start work for a caller that has already cancelled.
34
+ - Compensation and saga rollback report every failed undo, not only the first.
35
+ - Interview converges: answers populate the context, corrections replace earlier answers, and extraction validates against the schema. Creating an interview without a `contextSchema` throws.
36
+ - Replay reports a tampered trace. An edited event throws `ReplayDivergenceError`, and an edited output comes back with `matched: false`.
37
+ - A recorded model call stores the hash that replay compares it against, so replaying an unchanged call no longer logs a mismatch.
38
+ - Consultation enforces its latency budget while a specialist is running and no longer drops unavailable required specialists silently.
39
+ - Lock `extend()` writes a new entry, and in-memory lock state is per instance.
40
+ - Traces are no longer handed between concurrent callers through process-global state, and what is recorded matches the documented contract.
41
+ - `retry(0)`, non-finite vote confidences and non-positive round limits fail early or are clamped instead of propagating `undefined` or `NaN`.
42
+ - `sanitizeContext` handles circular objects and redacts inside arrays.
43
+
44
+ **@symplek/core, changed**
45
+ - `TrackedResult` values cannot be forged by constructing a look-alike object.
46
+ - `zod-to-json-schema` is a runtime dependency. It converts Zod 3 schemas; Zod 4 schemas use Zod's own converter.
47
+ - The debug cost line prints an estimate only for models with a known list price, and no figure otherwise.
48
+ - `openrouter` is not offered as a provider until it has a working adapter.
49
+ - The in-memory idempotency cache expires entries after one hour by default.
50
+
51
+ **@symplek/pro**
52
+ - Confidence, coherence, change-kernel, interview and the operators now re-export `@symplek/core` behind the license gate, replacing copies that had drifted from it.
53
+ - Importing without a license key fails with an error that names the one thing that fixes it: set `SYMPLEK_PRO_LICENSE_KEY` before the import. A malformed key gets its own error, which no longer echoes part of the key.
54
+ - TaCo consensus treats agreement as voters agreeing with each other, so a unanimous rejection converges.
55
+ - The antibody scanner gives the same verdict on the same input when a pattern carries the `g` flag.
56
+ - Stigmergy rejects evaporation rates that produced `NaN` confidence.
57
+ - The trust registry returns copies, so inspecting a grant cannot change it.
58
+ - `@symplek/core` is a caret peer range, where it used to pack as an exact version pin.
59
+ - A `test` script so the package's suite runs in CI.
60
+
61
+ All notable changes to this project will be documented in this file.
62
+
63
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
64
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
65
+
66
+ ## [Unreleased]
67
+
68
+ ## [1.0.0-beta.1] - 2026-04-13
69
+
70
+ ### Added
71
+
72
+ - **OC-0**: Initial package structure with AgentUnit algebra extracted from Convex source.
73
+ - **OC-0**: Tier boundary enforcement separating open-core surfaces from Convex-internal code.
74
+ - **OC-1**: Weft namespace facade (`Weft.stream`, `Weft.agent`, `Weft.configure`, `Weft.providers`).
75
+ - **OC-1**: WeftBuilder and AgentBuilder connected to the public API.
76
+ - **OC-1**: Golden-path test suite with 25 passing tests.
77
+ - **OC-1**: Quickstart documentation.
78
+ - **OC-2 DX**: `WeftError` messages include `[weft@VERSION]` prefix for self-identifying stack traces.
79
+ - **OC-2 DX**: Debug mode (`ai.debug = true`) logs one-line trace per AI call to stderr.
80
+ - **OC-2 DX**: Provider adapters surface missing API key as `WeftError` with `code: PROVIDER_ERROR`, `why`, `fix`, and `example` fields.
81
+ - **OC-2 DX**: JSDoc `@example`, `@param`, `@returns` added to all public `AgentUnit` methods and exported functions.
82
+ - **OC-2 PKG**: Package metadata complete for npm discoverability (`keywords`, `description`, `engines`).
83
+
84
+ ### Changed
85
+
86
+ - **OC-0**: Import path cleanup for published package layout and consumer ergonomics.
87
+
88
+ [Unreleased]: https://github.com/wefthq/weft/compare/weft-core@1.0.0-beta.1...HEAD
89
+ [1.0.0-beta.1]: https://github.com/wefthq/weft/releases/tag/weft-core@1.0.0-beta.1
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Symplek Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,241 @@
1
- # Temporary Holding Version
1
+ # @symplek/core
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ **Composable AI agents for TypeScript. Free, MIT-licensed.**
4
+
5
+ [![npm](https://img.shields.io/npm/v/@symplek/core)](https://www.npmjs.com/package/@symplek/core)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
7
+ [![Node.js](https://img.shields.io/badge/node-%3E%3D20-brightgreen)](package.json)
8
+
9
+ ---
10
+
11
+ ## Install
12
+
13
+ ```bash
14
+ pnpm add @symplek/core zod
15
+ # or
16
+ npm install @symplek/core zod
17
+ ```
18
+
19
+ Node 20 or later. `zod` is a required peer (3.25.28 or later, or 4.x). Schemas from either generation work at runtime. One typing gap: with zod 3.25 installed, a schema built from `zod/v4` does not type-check against the `schema` option, so install zod 4 if you write Zod 4 schemas.
20
+
21
+ To call a model you also need that provider's SDK and its API key:
22
+
23
+ | Provider | SDK to install | Key in the environment |
24
+ |---|---|---|
25
+ | `openai` | `openai` | `OPENAI_API_KEY` |
26
+ | `anthropic` | `@anthropic-ai/sdk` | `ANTHROPIC_API_KEY` |
27
+ | `google` | `@google/generative-ai` | `GOOGLE_GENERATIVE_AI_API_KEY` |
28
+
29
+ The composition operators need none of that. They work on any async function.
30
+
31
+ ---
32
+
33
+ ## Working in 3 lines
34
+
35
+ ```typescript
36
+ import { Symplek } from "@symplek/core/server";
37
+
38
+ Symplek.configure({ provider: "openai", apiKey: process.env.OPENAI_API_KEY });
39
+ const result = await Symplek("List three benefits of TypeScript");
40
+ console.log(result.value); // "1. Static typing catches errors early..."
41
+ ```
42
+
43
+ With the key already in the environment you can skip `configure()`. Symplek finds the key and loads the matching provider on the first call. If more than one provider key is set, it takes the first of OpenAI, Anthropic, Google.
44
+
45
+ > `@symplek/core/server` loads provider SDKs, so it is Node.js only. Browser-safe exports live at `@symplek/core`.
46
+
47
+ ---
48
+
49
+ ## What you get
50
+
51
+ - **Lazy units.** `AgentUnit<T>` builds a computation chain and runs nothing until `.run()` is called.
52
+ - **Parallel execution.** `AgentUnit.zipAll([a, b, c])` runs units side by side and returns the results in order.
53
+ - **Single-round consensus.** `.consensus([voter1, voter2, voter3])` polls the voters and tallies the vote. Every voter counts equally unless you pass `weights`; a voter's own `confidence` is recorded, not used as its weight.
54
+ - **Resilience operators.** `.retry(3)`, `.timeout(5000)` and `.fallback(backup)` compose on any unit.
55
+ - **A result envelope.** Every `.run()` returns a `TrackedResult<T>`: your value plus a source label and a confidence figure. Read [what those fields mean](#what-run-gives-you-back) before relying on them.
56
+ - **Structured output.** Pass a Zod schema and get a validated object back.
57
+ - **Streaming.** `Symplek.stream(task)` returns an `AsyncGenerator<string>` of output chunks.
58
+
59
+ ---
60
+
61
+ ## From simple to multi-agent
62
+
63
+ ### Step 1: one agent
64
+
65
+ ```typescript
66
+ import { Symplek } from "@symplek/core/server";
67
+
68
+ Symplek.configure({ provider: "openai", apiKey: process.env.OPENAI_API_KEY });
69
+
70
+ const result = await Symplek("What is the capital of France?");
71
+ console.log(result.value); // "Paris"
72
+ ```
73
+
74
+ ### Step 2: agents in parallel
75
+
76
+ ```typescript
77
+ import { Symplek, AgentUnit, createContext } from "@symplek/core/server";
78
+
79
+ const ctx = createContext();
80
+
81
+ const result = await AgentUnit.zipAll([
82
+ Symplek.unit(async () => "low risk"),
83
+ Symplek.unit(async () => "proceed"),
84
+ ]).map(([analysis, recommendation]) => ({ analysis, recommendation })).run(ctx);
85
+
86
+ console.log(result.value); // { analysis: "low risk", recommendation: "proceed" }
87
+ ```
88
+
89
+ `Symplek.unit(fn)` is the same as `AgentUnit.from(fn)`, reachable from the namespace you already imported.
90
+
91
+ ### Step 3: consensus vote
92
+
93
+ ```typescript
94
+ import { Symplek, createContext } from "@symplek/core/server";
95
+
96
+ const ctx = createContext();
97
+
98
+ // Start from a Symplek(task) call and move into coordination with .coordinate()
99
+ const voted = await Symplek("Should we ship the feature?")
100
+ .coordinate()
101
+ .consensus([
102
+ (_) => ({ decision: "approve" as const, confidence: 0.9 }),
103
+ (_) => ({ decision: "approve" as const, confidence: 0.8 }),
104
+ (_) => ({ decision: "reject" as const, confidence: 0.6, reasoning: "Needs more testing" }),
105
+ ])
106
+ .run(ctx);
107
+
108
+ console.log(voted.value.approved); // true
109
+ console.log(voted.value.consensus); // "reached"
110
+ ```
111
+
112
+ Or start from a plain value with `Symplek.of`:
113
+
114
+ ```typescript
115
+ const voted = await Symplek.of("Ship the feature")
116
+ .consensus([voter1, voter2, voter3])
117
+ .run(ctx);
118
+ ```
119
+
120
+ ### Step 4: resilience
121
+
122
+ ```typescript
123
+ import { Symplek, createContext } from "@symplek/core/server";
124
+
125
+ const ctx = createContext();
126
+
127
+ type Reply = { cached: boolean; result: string };
128
+
129
+ const robust = Symplek
130
+ .unit<Reply>(async () => callExternalAPI())
131
+ .retry(3)
132
+ .timeout(10_000)
133
+ .fallback(Symplek.of<Reply>({ cached: true, result: "default response" }));
134
+
135
+ const result = await robust.run(ctx);
136
+ ```
137
+
138
+ `.timeout()` stops waiting after the deadline. It does not cancel the work underneath. The fallback has to produce the same type as the unit it backs up.
139
+
140
+ ---
141
+
142
+ ## Structured output
143
+
144
+ Pass a Zod schema and the reply comes back parsed and validated:
145
+
146
+ ```typescript
147
+ import { ai } from "@symplek/core/server";
148
+ import { z } from "zod";
149
+
150
+ const Review = z.object({
151
+ sentiment: z.enum(["positive", "negative"]),
152
+ tags: z.array(z.string()),
153
+ });
154
+
155
+ const review = await ai("Classify this review: fast delivery, great fit", { schema: Review });
156
+ console.log(review.sentiment); // "positive"
157
+ ```
158
+
159
+ Symplek sends the model the JSON Schema for your Zod type, asks for JSON only, then validates the reply. A reply that does not match throws a `SymplekError` with code `INVALID_SCHEMA`. Nothing forces the model to comply beyond that instruction (plus JSON mode on the providers that have one), so plan for the error on weaker models.
160
+
161
+ ---
162
+
163
+ ## Which model runs
164
+
165
+ Set one yourself and that is the one that runs: `Symplek.configure({ model })`, or the `model` option on a call.
166
+
167
+ If you set none, Symplek picks from a built-in table:
168
+
169
+ | Provider | Default | `quality: "high"` | `quality: "fast"` |
170
+ |---|---|---|---|
171
+ | `openai` | `gpt-4o-mini` | `gpt-4o` | `gpt-4o-mini` |
172
+ | `anthropic` | `claude-sonnet-5-5` | `claude-opus-5-5` | `claude-haiku-5-5` |
173
+ | `google` | `gemini-3.8-flash` | `gemini-3.8-flash` | `gemini-3.5-flash-lite` |
174
+
175
+ One thing to know about before it shows up on a bill. With no model and no `quality` set, a prompt longer than 500 characters, or one containing "analyze", "complex", "reason", "think", "evaluate", "summarize" or "extract", is sent to the `high` column. Set `model` or `quality` if you want to decide that yourself.
176
+
177
+ Providers retire model ids. If a default stops working, set `model` explicitly and upgrade when a release updates the table.
178
+
179
+ Two provider behaviours worth knowing. The Anthropic adapter does not forward `temperature` or `topP`, because current Claude models reject them. When a provider declines a request, the call throws `PROVIDER_ERROR`. Reaching the output limit before writing any answer text also throws `PROVIDER_ERROR`. A call that stops normally before writing any text returns an empty string.
180
+
181
+ ---
182
+
183
+ ## What `.run()` gives you back
184
+
185
+ `.run(ctx)` resolves to a `TrackedResult<T>`: `value`, `source`, `confidence`, `sourceChain` and `minChainConfidence`.
186
+
187
+ Be clear about what the numbers are:
188
+
189
+ - `source` is `"agent"` for everything `.run()` produces. `.tracked({ source, confidence })` attaches your own label, which you then read at `result.value.source`: the outer envelope still says `"agent"`.
190
+ - `confidence` starts at 0.85 and moves by a fixed amount per operator in the chain (for example +0.10 for `consensus`, -0.05 for `retry`). It never looks at the output.
191
+ - `objectiveConfidence`, on consensus and debate results, is the figure calculated from the votes themselves.
192
+
193
+ The [root README](../../README.md#what-run-gives-you-back) has the full table.
194
+
195
+ ---
196
+
197
+ ## Record and replay
198
+
199
+ `.rehearse()` runs a unit once and records the outcome. `.replay(trace)` returns that stored outcome later without running the unit, after checking the trace has not been altered.
200
+
201
+ It records the final output, not the steps inside the unit, and replay does not re-run your agent. The [root README](../../README.md#record-and-replay) says exactly what it does and does not do.
202
+
203
+ ---
204
+
205
+ ## Key exports
206
+
207
+ | Export | From | Description |
208
+ |---|---|---|
209
+ | `AgentUnit` | `@symplek/core` | The lazy unit: `.from()`, `.of()`, `.map()`, `.flatMap()`, `.zipAll()`, `.race()` and the operators above |
210
+ | `createContext` | `@symplek/core` | Creates the `AgentContext` that `.run()` takes. Works with no arguments |
211
+ | `SymplekError` | `@symplek/core` | Structured error with `.code`, `.message` and `.action` |
212
+ | `InMemoryIdempotencyStore` | `@symplek/core` | Idempotency store for `.run(ctx, { idempotency })`. Dedupes side-effecting runs (`reject` or `return-cached`, optional TTL) |
213
+ | `Symplek` | `@symplek/core/server` | The facade: `Symplek(task)`, `.run()`, `.stream()`, `.agent()`, `.unit()`, `.of()`, `.configure()`, `.providers()` |
214
+ | `ai` | `@symplek/core/server` | One model call, with an optional Zod `schema` |
215
+
216
+ ---
217
+
218
+ ## Need more?
219
+
220
+ Everything above is in `@symplek/core` under MIT, along with teams, the solo gate, coherence, confidence, interview, change-kernel, contracts and observability.
221
+
222
+ [`@symplek/pro`](../symplek-pro/README.md) adds four things, behind a license key:
223
+
224
+ - **Multi-round TaCo consensus.** Agents see each other's rationale and revote until they converge.
225
+ - **Stigmergic confidence.** Pheromone-style coordination with evaporation and decay.
226
+ - **Agent antibodies.** Scans agent output against registered patterns: reject, warn or quarantine.
227
+ - **Trust registry.** Trusted-traveler lanes with a configurable scan depth per agent.
228
+
229
+ ---
230
+
231
+ ## Links
232
+
233
+ - [Record and replay](../../docs/ARCHITECTURE.md): what `.rehearse()` and `.replay()` do, and the pieces underneath
234
+ - [Tier boundary](../../docs/tier-boundary.md): what is in `@symplek/core` and what is in `@symplek/pro`
235
+ - [GitHub](https://github.com/symplek/symplek)
236
+
237
+ ---
238
+
239
+ ## License
240
+
241
+ MIT
@@ -0,0 +1,20 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
+
3
+
4
+
5
+
6
+
7
+ var _chunkIJP2U2XScjs = require('../chunk-IJP2U2XS.cjs');
8
+
9
+ // src/agent/tool.ts
10
+ function tool(config) {
11
+ return config;
12
+ }
13
+
14
+
15
+
16
+
17
+
18
+
19
+
20
+ exports.DEFAULT_LOOP_OPTIONS = _chunkIJP2U2XScjs.DEFAULT_LOOP_OPTIONS; exports.ToolApprovalRequiredError = _chunkIJP2U2XScjs.ToolApprovalRequiredError; exports.createToolApprovalComputation = _chunkIJP2U2XScjs.createToolApprovalComputation; exports.createToolApprovalGateComputation = _chunkIJP2U2XScjs.createToolApprovalGateComputation; exports.stopWhen = _chunkIJP2U2XScjs.stopWhen; exports.tool = tool;
@@ -0,0 +1,3 @@
1
+ export { bk as DEFAULT_LOOP_OPTIONS, bl as LoopExecuteOptions, bm as LoopOperatorOptions, aa as LoopOptions, bn as StepInfo, bo as StepModifications, a9 as Tool, bj as ToolApprovalPayload, bp as stopWhen, bq as tool } from '../runStandalone-Dql9RPr8.cjs';
2
+ export { T as ToolApprovalPending, b as ToolApprovalRequiredError, d as createToolApprovalComputation, e as createToolApprovalGateComputation } from '../index-idgX6aVg.cjs';
3
+ import 'zod';
@@ -0,0 +1,3 @@
1
+ export { bk as DEFAULT_LOOP_OPTIONS, bl as LoopExecuteOptions, bm as LoopOperatorOptions, aa as LoopOptions, bn as StepInfo, bo as StepModifications, a9 as Tool, bj as ToolApprovalPayload, bp as stopWhen, bq as tool } from '../runStandalone-Dql9RPr8.js';
2
+ export { T as ToolApprovalPending, b as ToolApprovalRequiredError, d as createToolApprovalComputation, e as createToolApprovalGateComputation } from '../index-BiYShIGN.js';
3
+ import 'zod';
@@ -0,0 +1,20 @@
1
+ import {
2
+ DEFAULT_LOOP_OPTIONS,
3
+ ToolApprovalRequiredError,
4
+ createToolApprovalComputation,
5
+ createToolApprovalGateComputation,
6
+ stopWhen
7
+ } from "../chunk-XSO3HG4U.js";
8
+
9
+ // src/agent/tool.ts
10
+ function tool(config) {
11
+ return config;
12
+ }
13
+ export {
14
+ DEFAULT_LOOP_OPTIONS,
15
+ ToolApprovalRequiredError,
16
+ createToolApprovalComputation,
17
+ createToolApprovalGateComputation,
18
+ stopWhen,
19
+ tool
20
+ };