@xandreed/core 0.3.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 (95) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +5 -0
  3. package/dist/domain/agent-failure.entity.d.ts +12 -0
  4. package/dist/domain/agent-failure.entity.functions.d.ts +5 -0
  5. package/dist/domain/agent-failure.entity.functions.js +8 -0
  6. package/dist/domain/agent-failure.entity.js +8 -0
  7. package/dist/domain/failure.entity.d.ts +12 -0
  8. package/dist/domain/failure.entity.functions.d.ts +3 -0
  9. package/dist/domain/failure.entity.functions.js +1 -0
  10. package/dist/domain/failure.entity.js +5 -0
  11. package/dist/domain/loop-event.entity.d.ts +94 -0
  12. package/dist/domain/loop-event.entity.js +0 -0
  13. package/dist/domain/message.entity.d.ts +227 -0
  14. package/dist/domain/message.entity.js +51 -0
  15. package/dist/domain/model-call-policy.entity.d.ts +12 -0
  16. package/dist/domain/model-call-policy.entity.js +5 -0
  17. package/dist/domain/model-catalog.entity.d.ts +10 -0
  18. package/dist/domain/model-catalog.entity.js +7 -0
  19. package/dist/domain/model-selection.entity.d.ts +24 -0
  20. package/dist/domain/model-selection.entity.functions.d.ts +5 -0
  21. package/dist/domain/model-selection.entity.functions.js +9 -0
  22. package/dist/domain/model-selection.entity.js +8 -0
  23. package/dist/domain/prompt-provenance.entity.d.ts +11 -0
  24. package/dist/domain/prompt-provenance.entity.js +8 -0
  25. package/dist/domain/token-usage.entity.d.ts +9 -0
  26. package/dist/domain/token-usage.entity.functions.d.ts +3 -0
  27. package/dist/domain/token-usage.entity.functions.js +11 -0
  28. package/dist/domain/token-usage.entity.js +7 -0
  29. package/dist/harness/capability.entity.d.ts +61 -0
  30. package/dist/harness/capability.entity.functions.d.ts +6 -0
  31. package/dist/harness/capability.entity.functions.js +10 -0
  32. package/dist/harness/capability.entity.js +26 -0
  33. package/dist/harness/capability.test.d.ts +1 -0
  34. package/dist/harness/config.entity.d.ts +48 -0
  35. package/dist/harness/config.entity.functions.d.ts +3 -0
  36. package/dist/harness/config.entity.functions.js +1 -0
  37. package/dist/harness/config.entity.js +18 -0
  38. package/dist/harness/plugin.adapter.d.ts +18 -0
  39. package/dist/harness/plugin.adapter.js +13 -0
  40. package/dist/harness/plugin.entity.d.ts +25 -0
  41. package/dist/harness/plugin.entity.js +9 -0
  42. package/dist/harness/session.entity.d.ts +33 -0
  43. package/dist/harness/session.entity.js +25 -0
  44. package/dist/index.d.ts +51 -0
  45. package/dist/index.js +99 -0
  46. package/dist/loop/cacheKey.d.ts +13 -0
  47. package/dist/loop/cacheKey.js +2 -0
  48. package/dist/loop/mapping.d.ts +79 -0
  49. package/dist/loop/mapping.js +154 -0
  50. package/dist/loop/mapping.test.d.ts +1 -0
  51. package/dist/loop/modelPolicy.d.ts +21 -0
  52. package/dist/loop/modelPolicy.js +2 -0
  53. package/dist/loop/promptProvenance.d.ts +8 -0
  54. package/dist/loop/promptProvenance.js +2 -0
  55. package/dist/loop/stepContext.d.ts +3 -0
  56. package/dist/loop/stepContext.js +2 -0
  57. package/dist/loop/streamFold.d.ts +31 -0
  58. package/dist/loop/streamFold.js +58 -0
  59. package/dist/loop/streamFold.test.d.ts +1 -0
  60. package/dist/mcp/bridge.d.ts +51 -0
  61. package/dist/mcp/bridge.js +70 -0
  62. package/dist/mcp/bridge.test.d.ts +1 -0
  63. package/dist/ports/auth-store.port.d.ts +50 -0
  64. package/dist/ports/auth-store.port.js +18 -0
  65. package/dist/ports/capability.port.d.ts +15 -0
  66. package/dist/ports/capability.port.js +7 -0
  67. package/dist/ports/conversation-store.port.d.ts +250 -0
  68. package/dist/ports/conversation-store.port.js +36 -0
  69. package/dist/ports/file-system.port.d.ts +26 -0
  70. package/dist/ports/file-system.port.js +10 -0
  71. package/dist/ports/harness.port.d.ts +106 -0
  72. package/dist/ports/harness.port.js +31 -0
  73. package/dist/ports/mcp-client.port.d.ts +74 -0
  74. package/dist/ports/mcp-client.port.js +24 -0
  75. package/dist/ports/model-catalog.port.d.ts +10 -0
  76. package/dist/ports/model-catalog.port.js +4 -0
  77. package/dist/ports/settings-store.port.d.ts +85 -0
  78. package/dist/ports/settings-store.port.js +36 -0
  79. package/dist/ports/shell.port.d.ts +44 -0
  80. package/dist/ports/shell.port.js +16 -0
  81. package/dist/ports/utility-llm.port.d.ts +48 -0
  82. package/dist/ports/utility-llm.port.js +16 -0
  83. package/dist/session/chassis.d.ts +59 -0
  84. package/dist/session/chassis.js +27 -0
  85. package/dist/session/chassis.test.d.ts +1 -0
  86. package/dist/spec/SpecDoc.d.ts +162 -0
  87. package/dist/spec/SpecDoc.js +59 -0
  88. package/dist/spec/codec.d.ts +30 -0
  89. package/dist/spec/codec.js +123 -0
  90. package/dist/spec/codec.test.d.ts +1 -0
  91. package/dist/spec/frontmatter.d.ts +16 -0
  92. package/dist/spec/frontmatter.js +25 -0
  93. package/dist/util/json.d.ts +19 -0
  94. package/dist/util/json.js +15 -0
  95. package/package.json +30 -0
@@ -0,0 +1,61 @@
1
+ import { Schema } from "effect";
2
+ export declare const CapabilityTool: Schema.Struct<{
3
+ id: typeof Schema.NonEmptyTrimmedString;
4
+ version: typeof Schema.NonEmptyTrimmedString;
5
+ description: typeof Schema.NonEmptyTrimmedString;
6
+ returns: typeof Schema.NonEmptyTrimmedString;
7
+ permissions: Schema.Array$<typeof Schema.String>;
8
+ inputSchema: Schema.Record$<typeof Schema.String, typeof Schema.Unknown>;
9
+ outputSchema: Schema.Record$<typeof Schema.String, typeof Schema.Unknown>;
10
+ }>;
11
+ export type CapabilityTool = typeof CapabilityTool.Type;
12
+ export declare const CapabilityRecipe: Schema.Struct<{
13
+ id: typeof Schema.NonEmptyTrimmedString;
14
+ version: typeof Schema.NonEmptyTrimmedString;
15
+ instructions: typeof Schema.NonEmptyTrimmedString;
16
+ tools: Schema.Array$<typeof Schema.NonEmptyTrimmedString>;
17
+ }>;
18
+ export type CapabilityRecipe = typeof CapabilityRecipe.Type;
19
+ export declare const CapabilityCatalog: Schema.Struct<{
20
+ version: typeof Schema.NonEmptyTrimmedString;
21
+ recipes: Schema.Array$<Schema.Struct<{
22
+ id: typeof Schema.NonEmptyTrimmedString;
23
+ version: typeof Schema.NonEmptyTrimmedString;
24
+ instructions: typeof Schema.NonEmptyTrimmedString;
25
+ tools: Schema.Array$<typeof Schema.NonEmptyTrimmedString>;
26
+ }>>;
27
+ tools: Schema.Array$<Schema.Struct<{
28
+ id: typeof Schema.NonEmptyTrimmedString;
29
+ version: typeof Schema.NonEmptyTrimmedString;
30
+ description: typeof Schema.NonEmptyTrimmedString;
31
+ returns: typeof Schema.NonEmptyTrimmedString;
32
+ permissions: Schema.Array$<typeof Schema.String>;
33
+ inputSchema: Schema.Record$<typeof Schema.String, typeof Schema.Unknown>;
34
+ outputSchema: Schema.Record$<typeof Schema.String, typeof Schema.Unknown>;
35
+ }>>;
36
+ }>;
37
+ export type CapabilityCatalog = typeof CapabilityCatalog.Type;
38
+ export declare const CapabilitySelection: Schema.Struct<{
39
+ recipes: Schema.Array$<typeof Schema.String>;
40
+ tools: Schema.Array$<typeof Schema.String>;
41
+ }>;
42
+ export type CapabilitySelection = typeof CapabilitySelection.Type;
43
+ export declare const ResolvedCapabilities: Schema.Struct<{
44
+ catalogVersion: typeof Schema.String;
45
+ recipes: Schema.Array$<Schema.Struct<{
46
+ id: typeof Schema.NonEmptyTrimmedString;
47
+ version: typeof Schema.NonEmptyTrimmedString;
48
+ instructions: typeof Schema.NonEmptyTrimmedString;
49
+ tools: Schema.Array$<typeof Schema.NonEmptyTrimmedString>;
50
+ }>>;
51
+ tools: Schema.Array$<Schema.Struct<{
52
+ id: typeof Schema.NonEmptyTrimmedString;
53
+ version: typeof Schema.NonEmptyTrimmedString;
54
+ description: typeof Schema.NonEmptyTrimmedString;
55
+ returns: typeof Schema.NonEmptyTrimmedString;
56
+ permissions: Schema.Array$<typeof Schema.String>;
57
+ inputSchema: Schema.Record$<typeof Schema.String, typeof Schema.Unknown>;
58
+ outputSchema: Schema.Record$<typeof Schema.String, typeof Schema.Unknown>;
59
+ }>>;
60
+ }>;
61
+ export type ResolvedCapabilities = typeof ResolvedCapabilities.Type;
@@ -0,0 +1,6 @@
1
+ import { Effect } from "effect";
2
+ import type { CapabilityCatalog, CapabilitySelection, ResolvedCapabilities } from "./capability.entity.js";
3
+ import { HarnessError } from "./plugin.entity.js";
4
+ /** Probabilistic intent never authorizes a capability. Expansions use this same
5
+ * deterministic resolver against the run-pinned catalog and current grants. */
6
+ export declare const resolveCapabilities: (catalog: CapabilityCatalog, requested: CapabilitySelection, permissions: ReadonlySet<string>) => Effect.Effect<ResolvedCapabilities, HarnessError>;
@@ -0,0 +1,10 @@
1
+ import { Effect } from "effect";
2
+ import { HarnessError } from "./plugin.entity.js";
3
+ export const resolveCapabilities = (catalog, requested, permissions) => Effect.gen(function* () {
4
+ const recipeIds = new Set(requested.recipes), recipes = catalog.recipes.filter((recipe) => recipeIds.has(recipe.id)), toolIds = new Set([...requested.tools, ...recipes.flatMap((recipe) => recipe.tools)]), tools = catalog.tools.filter((tool) => toolIds.has(tool.id));
5
+ if (new Set(catalog.recipes.map((recipe) => recipe.id)).size !== catalog.recipes.length || new Set(catalog.tools.map((tool) => tool.id)).size !== catalog.tools.length || recipes.length !== recipeIds.size || tools.length !== toolIds.size)
6
+ return yield* Effect.fail(new HarnessError({ code: "capability.catalog", message: "Selection references an ambiguous or missing capability" }));
7
+ if (tools.some((tool) => tool.permissions.some((permission) => !permissions.has(permission))))
8
+ return yield* Effect.fail(new HarnessError({ code: "capability.forbidden", message: "Selection requires unavailable permissions" }));
9
+ return { catalogVersion: catalog.version, recipes, tools };
10
+ });
@@ -0,0 +1,26 @@
1
+ import { Schema } from "effect";
2
+ export const CapabilityTool = Schema.Struct({
3
+ id: Schema.NonEmptyTrimmedString,
4
+ version: Schema.NonEmptyTrimmedString,
5
+ description: Schema.NonEmptyTrimmedString,
6
+ returns: Schema.NonEmptyTrimmedString,
7
+ permissions: Schema.Array(Schema.String),
8
+ inputSchema: Schema.Record({ key: Schema.String, value: Schema.Unknown }),
9
+ outputSchema: Schema.Record({ key: Schema.String, value: Schema.Unknown })
10
+ }), CapabilityRecipe = Schema.Struct({
11
+ id: Schema.NonEmptyTrimmedString,
12
+ version: Schema.NonEmptyTrimmedString,
13
+ instructions: Schema.NonEmptyTrimmedString,
14
+ tools: Schema.Array(Schema.NonEmptyTrimmedString)
15
+ }), CapabilityCatalog = Schema.Struct({
16
+ version: Schema.NonEmptyTrimmedString,
17
+ recipes: Schema.Array(CapabilityRecipe),
18
+ tools: Schema.Array(CapabilityTool)
19
+ }), CapabilitySelection = Schema.Struct({
20
+ recipes: Schema.Array(Schema.String),
21
+ tools: Schema.Array(Schema.String)
22
+ }), ResolvedCapabilities = Schema.Struct({
23
+ catalogVersion: Schema.String,
24
+ recipes: Schema.Array(CapabilityRecipe),
25
+ tools: Schema.Array(CapabilityTool)
26
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,48 @@
1
+ import { Schema } from "effect";
2
+ import type { Plugin } from "./plugin.entity.js";
3
+ export declare const PluginEntry: Schema.Struct<{
4
+ id: typeof Schema.NonEmptyString;
5
+ use: typeof Schema.NonEmptyString;
6
+ enabled: Schema.optional<typeof Schema.Boolean>;
7
+ options: Schema.optional<Schema.Record$<typeof Schema.String, typeof Schema.Unknown>>;
8
+ }>;
9
+ export type PluginEntry = typeof PluginEntry.Type;
10
+ export declare const Profile: Schema.Struct<{
11
+ plugins: Schema.optional<Schema.Array$<Schema.Struct<{
12
+ id: typeof Schema.NonEmptyString;
13
+ use: typeof Schema.NonEmptyString;
14
+ enabled: Schema.optional<typeof Schema.Boolean>;
15
+ options: Schema.optional<Schema.Record$<typeof Schema.String, typeof Schema.Unknown>>;
16
+ }>>>;
17
+ bindings: Schema.optional<Schema.Record$<typeof Schema.String, typeof Schema.String>>;
18
+ system: Schema.optional<typeof Schema.String>;
19
+ }>;
20
+ export type Profile = typeof Profile.Type;
21
+ export declare const HarnessConfig: Schema.Struct<{
22
+ version: Schema.Literal<[1]>;
23
+ profile: Schema.optional<typeof Schema.String>;
24
+ plugins: Schema.optional<Schema.Array$<Schema.Struct<{
25
+ id: typeof Schema.NonEmptyString;
26
+ use: typeof Schema.NonEmptyString;
27
+ enabled: Schema.optional<typeof Schema.Boolean>;
28
+ options: Schema.optional<Schema.Record$<typeof Schema.String, typeof Schema.Unknown>>;
29
+ }>>>;
30
+ bindings: Schema.optional<Schema.Record$<typeof Schema.String, typeof Schema.String>>;
31
+ profiles: Schema.optional<Schema.Record$<typeof Schema.String, Schema.Struct<{
32
+ plugins: Schema.optional<Schema.Array$<Schema.Struct<{
33
+ id: typeof Schema.NonEmptyString;
34
+ use: typeof Schema.NonEmptyString;
35
+ enabled: Schema.optional<typeof Schema.Boolean>;
36
+ options: Schema.optional<Schema.Record$<typeof Schema.String, typeof Schema.Unknown>>;
37
+ }>>>;
38
+ bindings: Schema.optional<Schema.Record$<typeof Schema.String, typeof Schema.String>>;
39
+ system: Schema.optional<typeof Schema.String>;
40
+ }>>>;
41
+ system: Schema.optional<typeof Schema.String>;
42
+ }>;
43
+ export type HarnessConfig = typeof HarnessConfig.Type;
44
+ export interface AgentDefinition {
45
+ readonly id: string;
46
+ readonly config: HarnessConfig;
47
+ readonly plugins: ReadonlyArray<Plugin>;
48
+ }
@@ -0,0 +1,3 @@
1
+ import type { AgentDefinition, HarnessConfig } from "./config.entity.js";
2
+ export declare const defineConfig: <A extends HarnessConfig>(config: A) => A;
3
+ export declare const defineAgent: <A extends AgentDefinition>(agent: A) => A;
@@ -0,0 +1 @@
1
+ export const defineConfig = (config) => config, defineAgent = (agent) => agent;
@@ -0,0 +1,18 @@
1
+ import { Schema } from "effect";
2
+ export const PluginEntry = Schema.Struct({
3
+ id: Schema.NonEmptyString,
4
+ use: Schema.NonEmptyString,
5
+ enabled: Schema.optional(Schema.Boolean),
6
+ options: Schema.optional(Schema.Record({ key: Schema.String, value: Schema.Unknown }))
7
+ }), Profile = Schema.Struct({
8
+ plugins: Schema.optional(Schema.Array(PluginEntry)),
9
+ bindings: Schema.optional(Schema.Record({ key: Schema.String, value: Schema.String })),
10
+ system: Schema.optional(Schema.String)
11
+ }), HarnessConfig = Schema.Struct({
12
+ version: Schema.Literal(1),
13
+ profile: Schema.optional(Schema.String),
14
+ plugins: Schema.optional(Schema.Array(PluginEntry)),
15
+ bindings: Schema.optional(Schema.Record({ key: Schema.String, value: Schema.String })),
16
+ profiles: Schema.optional(Schema.Record({ key: Schema.String, value: Profile })),
17
+ system: Schema.optional(Schema.String)
18
+ });
@@ -0,0 +1,18 @@
1
+ import { Layer, Schema } from "effect";
2
+ import type { Plugin } from "./plugin.entity.js";
3
+ /** Layers retain their native types until the validated dynamic loading edge. */
4
+ export declare const definePlugin: <A extends Readonly<Record<string, unknown>>, I, Out, E, In>(definition: {
5
+ readonly id: string;
6
+ readonly version: string;
7
+ readonly apiVersion?: number;
8
+ readonly scope?: "runtime" | "session";
9
+ readonly requires?: ReadonlyArray<{
10
+ readonly key: string;
11
+ }>;
12
+ readonly provides: ReadonlyArray<{
13
+ readonly key: string;
14
+ }>;
15
+ readonly config: Schema.Schema<A, I>;
16
+ readonly defaults: A;
17
+ readonly layer: (config: A) => Layer.Layer<Out, E, In>;
18
+ }) => Plugin;
@@ -0,0 +1,13 @@
1
+ import { Context, Effect, Layer, Schema } from "effect";
2
+ import { HarnessError, PLUGIN_API_VERSION } from "./plugin.entity.js";
3
+ export const definePlugin = (definition) => ({
4
+ id: definition.id,
5
+ version: definition.version,
6
+ apiVersion: definition.apiVersion ?? PLUGIN_API_VERSION,
7
+ scope: definition.scope ?? "session",
8
+ requires: (definition.requires ?? []).map((tag) => tag.key),
9
+ provides: definition.provides.map((tag) => tag.key),
10
+ schema: definition.config,
11
+ defaults: definition.defaults,
12
+ build: (options, services) => Schema.decodeUnknown(definition.config)(options, { onExcessProperty: "error" }).pipe(Effect.flatMap((config) => Layer.build(definition.layer(config)).pipe(Effect.provide(Context.unsafeMake(services.unsafeMap)), Effect.map((built) => Context.unsafeMake(built.unsafeMap)))), Effect.mapError((error) => new HarnessError({ code: "plugin.activation", plugin: definition.id, message: String(error) })), Effect.catchAllDefect((error) => Effect.fail(new HarnessError({ code: "plugin.defect", plugin: definition.id, message: String(error) }))))
13
+ });
@@ -0,0 +1,25 @@
1
+ import { Schema } from "effect";
2
+ import type { Context, Effect, Scope } from "effect";
3
+ export declare const PLUGIN_API_VERSION = 1;
4
+ declare const HarnessError_base: Schema.TaggedErrorClass<HarnessError, "HarnessError", {
5
+ readonly _tag: Schema.tag<"HarnessError">;
6
+ } & {
7
+ code: typeof Schema.String;
8
+ message: typeof Schema.String;
9
+ plugin: Schema.optional<typeof Schema.String>;
10
+ }>;
11
+ export declare class HarnessError extends HarnessError_base {
12
+ }
13
+ /** The runtime consumes this erased boundary; authors use definePlugin. */
14
+ export interface Plugin {
15
+ readonly id: string;
16
+ readonly version: string;
17
+ readonly apiVersion: number;
18
+ readonly scope: "runtime" | "session";
19
+ readonly requires: ReadonlyArray<string>;
20
+ readonly provides: ReadonlyArray<string>;
21
+ readonly schema: Schema.Schema.AnyNoContext;
22
+ readonly defaults: Readonly<Record<string, unknown>>;
23
+ readonly build: (options: unknown, services: Context.Context<never>) => Effect.Effect<Context.Context<never>, HarnessError, Scope.Scope>;
24
+ }
25
+ export {};
@@ -0,0 +1,9 @@
1
+ import { Schema } from "effect";
2
+ export const PLUGIN_API_VERSION = 1;
3
+
4
+ export class HarnessError extends Schema.TaggedError()("HarnessError", {
5
+ code: Schema.String,
6
+ message: Schema.String,
7
+ plugin: Schema.optional(Schema.String)
8
+ }) {
9
+ }
@@ -0,0 +1,33 @@
1
+ import { Schema } from "effect";
2
+ export declare const SessionRecord: Schema.Struct<{
3
+ id: Schema.brand<typeof Schema.UUID, "ConversationId">;
4
+ workspace: typeof Schema.String;
5
+ profile: typeof Schema.String;
6
+ createdAt: typeof Schema.Number;
7
+ parent: Schema.optional<Schema.brand<typeof Schema.UUID, "ConversationId">>;
8
+ }>;
9
+ export type SessionRecord = typeof SessionRecord.Type;
10
+ export declare const EventBody: Schema.Struct<{
11
+ name: typeof Schema.NonEmptyString;
12
+ runId: Schema.optional<typeof Schema.String>;
13
+ data: Schema.Record$<typeof Schema.String, typeof Schema.Unknown>;
14
+ }>;
15
+ export type EventBody = typeof EventBody.Type;
16
+ export declare const SessionEvent: Schema.Struct<{
17
+ version: Schema.Literal<[1]>;
18
+ id: typeof Schema.String;
19
+ sessionId: Schema.brand<typeof Schema.UUID, "ConversationId">;
20
+ seq: typeof Schema.Int;
21
+ at: typeof Schema.Number;
22
+ name: typeof Schema.NonEmptyString;
23
+ runId: Schema.optional<typeof Schema.String>;
24
+ data: Schema.Record$<typeof Schema.String, typeof Schema.Unknown>;
25
+ }>;
26
+ export type SessionEvent = typeof SessionEvent.Type;
27
+ export declare const MemoryEntry: Schema.Struct<{
28
+ id: typeof Schema.String;
29
+ workspace: typeof Schema.String;
30
+ text: typeof Schema.String;
31
+ createdAt: typeof Schema.Number;
32
+ }>;
33
+ export type MemoryEntry = typeof MemoryEntry.Type;
@@ -0,0 +1,25 @@
1
+ import { Schema } from "effect";
2
+ import { ConversationId } from "../domain/message.entity.js";
3
+ export const SessionRecord = Schema.Struct({
4
+ id: ConversationId,
5
+ workspace: Schema.String,
6
+ profile: Schema.String,
7
+ createdAt: Schema.Number,
8
+ parent: Schema.optional(ConversationId)
9
+ }), EventBody = Schema.Struct({
10
+ name: Schema.NonEmptyString,
11
+ runId: Schema.optional(Schema.String),
12
+ data: Schema.Record({ key: Schema.String, value: Schema.Unknown })
13
+ }), SessionEvent = Schema.Struct({
14
+ ...EventBody.fields,
15
+ version: Schema.Literal(1),
16
+ id: Schema.String,
17
+ sessionId: ConversationId,
18
+ seq: Schema.Int,
19
+ at: Schema.Number
20
+ }), MemoryEntry = Schema.Struct({
21
+ id: Schema.String,
22
+ workspace: Schema.String,
23
+ text: Schema.String,
24
+ createdAt: Schema.Number
25
+ });
@@ -0,0 +1,51 @@
1
+ export { AgentMessage, AgentResult, AssistantMessage, Checkpoint, ConversationId, ReasoningPart, TextPart, ToolCallId, ToolCallPart, ToolMessage, ToolResultPart, UserMessage, } from "./domain/message.entity.js";
2
+ export { Failure } from "./domain/failure.entity.js";
3
+ export { toFailure } from "./domain/failure.entity.functions.js";
4
+ export { AgentFailure, AgentFailureCategory } from "./domain/agent-failure.entity.js";
5
+ export type { AgentFailure as AgentFailureType, AgentFailureCategory as AgentFailureCategoryType } from "./domain/agent-failure.entity.js";
6
+ export { toAgentFailure, toolResultFailure } from "./domain/agent-failure.entity.functions.js";
7
+ export { TokenUsage } from "./domain/token-usage.entity.js";
8
+ export { addUsage, zeroUsage } from "./domain/token-usage.entity.functions.js";
9
+ export { ModelId, ModelSelection, ProviderId, } from "./domain/model-selection.entity.js";
10
+ export { ModelCallPolicy, ReasoningEffort } from "./domain/model-call-policy.entity.js";
11
+ export type { ReasoningEffort as ReasoningEffortType } from "./domain/model-call-policy.entity.js";
12
+ export { ModelCatalogEntry } from "./domain/model-catalog.entity.js";
13
+ export type { ModelCatalogEntry as ModelCatalogEntryType } from "./domain/model-catalog.entity.js";
14
+ export type { ModelCallPolicy as ModelCallPolicyType } from "./domain/model-call-policy.entity.js";
15
+ export { CurrentEmptyResponseTolerance, CurrentModelCallPolicy } from "./loop/modelPolicy.js";
16
+ export { formatModelSelection, parseModelSelection } from "./domain/model-selection.entity.functions.js";
17
+ export type { LoopEvent, ToolCallSummary } from "./domain/loop-event.entity.js";
18
+ export { ConversationStore, ConversationSummary, RunOutcomeRecord, StoredMessage, StoreError, } from "./ports/conversation-store.port.js";
19
+ export { EngineSettings, SETTINGS_KEYS, SettingsError, SettingsStore, } from "./ports/settings-store.port.js";
20
+ export type { ModelRole, SettingsKey } from "./ports/settings-store.port.js";
21
+ export { AuthError, AuthStore, Credential } from "./ports/auth-store.port.js";
22
+ export { ModelCatalog } from "./ports/model-catalog.port.js";
23
+ export { FileSystem, FsError } from "./ports/file-system.port.js";
24
+ export { Shell, ShellError, ShellResult } from "./ports/shell.port.js";
25
+ export { UtilityCompletion, UtilityError, UtilityLlm } from "./ports/utility-llm.port.js";
26
+ export { asJsonRecord, decodeJsonLines, parseJsonOption, parseJsonWarn } from "./util/json.js";
27
+ export { assistantModel, assistantUsage, extractUsage, extractModel, handoffToMessage, safeKeepFrom, responseReasoning, responseText, responseToAgentMessages, responseToolCalls, responseToolResults, toPromptMessages, withToolCallIds, withUsageOnAssistant, } from "./loop/mapping.js";
28
+ export type { ToolResultSummary } from "./loop/mapping.js";
29
+ export { CurrentPromptCacheKey } from "./loop/cacheKey.js";
30
+ export { foldStreamParts } from "./loop/streamFold.js";
31
+ export type { FoldedTurn, StreamDelta } from "./loop/streamFold.js";
32
+ export { McpCallOutcome, McpClient, McpError, McpToolDescriptor } from "./ports/mcp-client.port.js";
33
+ export { buildMcpBridge, emptyMcpBridge, McpCall, McpDescribe } from "./mcp/bridge.js";
34
+ export type { McpBridge, McpBridgedTool } from "./mcp/bridge.js";
35
+ export { makeSession } from "./session/chassis.js";
36
+ export type { SeqEvent, Session } from "./session/chassis.js";
37
+ export { DEFAULT_SPEC_LIMITS, renderSpecSection, SpecCheck, SpecDoc, SpecGates, SpecLimits, SpecSlug, SpecStatus, } from "./spec/SpecDoc.js";
38
+ export { decodeSpecDocText, encodeSpecDocText, SpecDocParseError, specSlug, uniqueSlug, } from "./spec/codec.js";
39
+ export { parseFrontmatter } from "./spec/frontmatter.js";
40
+ export * from "./harness/plugin.entity.js";
41
+ export * from "./harness/plugin.adapter.js";
42
+ export * from "./harness/config.entity.js";
43
+ export * from "./harness/session.entity.js";
44
+ export * from "./ports/harness.port.js";
45
+ export { defineAgent, defineConfig } from "./harness/config.entity.functions.js";
46
+ export * from "./harness/capability.entity.js";
47
+ export * from "./harness/capability.entity.functions.js";
48
+ export * from "./ports/capability.port.js";
49
+ export * from "./domain/prompt-provenance.entity.js";
50
+ export * from "./loop/promptProvenance.js";
51
+ export { CurrentAgentStep } from "./loop/stepContext.js";
package/dist/index.js ADDED
@@ -0,0 +1,99 @@
1
+ export {
2
+ AgentMessage,
3
+ AgentResult,
4
+ AssistantMessage,
5
+ Checkpoint,
6
+ ConversationId,
7
+ ReasoningPart,
8
+ TextPart,
9
+ ToolCallId,
10
+ ToolCallPart,
11
+ ToolMessage,
12
+ ToolResultPart,
13
+ UserMessage
14
+ } from "./domain/message.entity.js";
15
+ export { Failure } from "./domain/failure.entity.js";
16
+ export { toFailure } from "./domain/failure.entity.functions.js";
17
+ export { AgentFailure, AgentFailureCategory } from "./domain/agent-failure.entity.js";
18
+ export { toAgentFailure, toolResultFailure } from "./domain/agent-failure.entity.functions.js";
19
+ export { TokenUsage } from "./domain/token-usage.entity.js";
20
+ export { addUsage, zeroUsage } from "./domain/token-usage.entity.functions.js";
21
+ export {
22
+ ModelId,
23
+ ModelSelection,
24
+ ProviderId
25
+ } from "./domain/model-selection.entity.js";
26
+ export { ModelCallPolicy, ReasoningEffort } from "./domain/model-call-policy.entity.js";
27
+ export { ModelCatalogEntry } from "./domain/model-catalog.entity.js";
28
+ export { CurrentEmptyResponseTolerance, CurrentModelCallPolicy } from "./loop/modelPolicy.js";
29
+ export { formatModelSelection, parseModelSelection } from "./domain/model-selection.entity.functions.js";
30
+ export {
31
+ ConversationStore,
32
+ ConversationSummary,
33
+ RunOutcomeRecord,
34
+ StoredMessage,
35
+ StoreError
36
+ } from "./ports/conversation-store.port.js";
37
+ export {
38
+ EngineSettings,
39
+ SETTINGS_KEYS,
40
+ SettingsError,
41
+ SettingsStore
42
+ } from "./ports/settings-store.port.js";
43
+ export { AuthError, AuthStore, Credential } from "./ports/auth-store.port.js";
44
+ export { ModelCatalog } from "./ports/model-catalog.port.js";
45
+ export { FileSystem, FsError } from "./ports/file-system.port.js";
46
+ export { Shell, ShellError, ShellResult } from "./ports/shell.port.js";
47
+ export { UtilityCompletion, UtilityError, UtilityLlm } from "./ports/utility-llm.port.js";
48
+ export { asJsonRecord, decodeJsonLines, parseJsonOption, parseJsonWarn } from "./util/json.js";
49
+ export {
50
+ assistantModel,
51
+ assistantUsage,
52
+ extractUsage,
53
+ extractModel,
54
+ handoffToMessage,
55
+ safeKeepFrom,
56
+ responseReasoning,
57
+ responseText,
58
+ responseToAgentMessages,
59
+ responseToolCalls,
60
+ responseToolResults,
61
+ toPromptMessages,
62
+ withToolCallIds,
63
+ withUsageOnAssistant
64
+ } from "./loop/mapping.js";
65
+ export { CurrentPromptCacheKey } from "./loop/cacheKey.js";
66
+ export { foldStreamParts } from "./loop/streamFold.js";
67
+ export { McpCallOutcome, McpClient, McpError, McpToolDescriptor } from "./ports/mcp-client.port.js";
68
+ export { buildMcpBridge, emptyMcpBridge, McpCall, McpDescribe } from "./mcp/bridge.js";
69
+ export { makeSession } from "./session/chassis.js";
70
+ export {
71
+ DEFAULT_SPEC_LIMITS,
72
+ renderSpecSection,
73
+ SpecCheck,
74
+ SpecDoc,
75
+ SpecGates,
76
+ SpecLimits,
77
+ SpecSlug,
78
+ SpecStatus
79
+ } from "./spec/SpecDoc.js";
80
+ export {
81
+ decodeSpecDocText,
82
+ encodeSpecDocText,
83
+ SpecDocParseError,
84
+ specSlug,
85
+ uniqueSlug
86
+ } from "./spec/codec.js";
87
+ export { parseFrontmatter } from "./spec/frontmatter.js";
88
+ export * from "./harness/plugin.entity.js";
89
+ export * from "./harness/plugin.adapter.js";
90
+ export * from "./harness/config.entity.js";
91
+ export * from "./harness/session.entity.js";
92
+ export * from "./ports/harness.port.js";
93
+ export { defineAgent, defineConfig } from "./harness/config.entity.functions.js";
94
+ export * from "./harness/capability.entity.js";
95
+ export * from "./harness/capability.entity.functions.js";
96
+ export * from "./ports/capability.port.js";
97
+ export * from "./domain/prompt-provenance.entity.js";
98
+ export * from "./loop/promptProvenance.js";
99
+ export { CurrentAgentStep } from "./loop/stepContext.js";
@@ -0,0 +1,13 @@
1
+ import { FiberRef, Option } from "effect";
2
+ /**
3
+ * The CURRENT conversation's cache identity, stamped by `runAgent` for the
4
+ * duration of a run. Adapters that can key server-side prompt caches on a
5
+ * stable id (OpenAI-compatible `prompt_cache_key`) read it at call time —
6
+ * one conversation, one cache lane, so parallel sessions stop evicting
7
+ * each other's prefixes. `None` (the default) sends nothing.
8
+ *
9
+ * A FiberRef, not a port: it's ambient call metadata, not a capability —
10
+ * and it must flow through the loop's fibers without threading a parameter
11
+ * through every seam.
12
+ */
13
+ export declare const CurrentPromptCacheKey: FiberRef.FiberRef<Option.Option<string>>;
@@ -0,0 +1,2 @@
1
+ import { FiberRef, GlobalValue, Option } from "effect";
2
+ export const CurrentPromptCacheKey = GlobalValue.globalValue("@xandreed/core/CurrentPromptCacheKey", () => FiberRef.unsafeMake(Option.none()));
@@ -0,0 +1,79 @@
1
+ import { Option } from "effect";
2
+ import type { ToolCallSummary } from "../domain/loop-event.entity.js";
3
+ import type { AgentMessage } from "../domain/message.entity.js";
4
+ import type { TokenUsage } from "../domain/token-usage.entity.js";
5
+ /**
6
+ * Bridges the persisted `AgentMessage` with `@effect/ai`'s `Prompt`/`Response`
7
+ * encodings. The opaque provider blob is carried verbatim both ways —
8
+ * `AgentMessage.providerOptions ↔ prompt part options ↔ response part
9
+ * metadata` — which is how Gemini's `thought_signature` round-trips across
10
+ * turns (the framework's own `fromResponseParts` drops it, so the engine maps
11
+ * by hand and keeps the blob). Everything here is pure: no mutation, no IO.
12
+ */
13
+ /** Wrap a fold summary as the single user message standing in for the folded
14
+ * history — prepended by `runAgent` when the conversation has a checkpoint. */
15
+ export declare const handoffToMessage: (summary: string) => AgentMessage;
16
+ /**
17
+ * The largest SAFE fold cut keeping at least `keepTurns` assistant turns
18
+ * verbatim: the cut always lands ON an assistant message (a tool message
19
+ * follows its assistant, so a tool-call is never split from its results),
20
+ * and never at index 0 (something must fold). `None` when the buffer is too
21
+ * small to fold at all.
22
+ */
23
+ export declare const safeKeepFrom: (messages: ReadonlyArray<AgentMessage>, keepTurns: number) => Option.Option<number>;
24
+ /** `AgentMessage[]` → `@effect/ai` encoded prompt messages (spreadable). */
25
+ export declare const toPromptMessages: (messages: ReadonlyArray<AgentMessage>) => ReadonlyArray<unknown>;
26
+ /**
27
+ * Some providers (notably Gemini) return tool calls WITHOUT an id. An absent
28
+ * id breaks durable UI identity (a live event and a later re-projection of
29
+ * the same persisted message must compute the same key), so a deterministic
30
+ * id — `<turnIndex>:<toolName>:<ordinalInTurn>` — is minted ONCE here, before
31
+ * the content fans out into events and persisted messages. The Nth id-less
32
+ * call and the Nth id-less result pair on the same ordinal, so the
33
+ * call ↔ result pairing stays valid. A non-empty provider id is left as-is.
34
+ *
35
+ * Pure: returns new part objects; the input is never mutated.
36
+ */
37
+ export declare const withToolCallIds: (content: ReadonlyArray<unknown>, turnIndex: number) => ReadonlyArray<unknown>;
38
+ /**
39
+ * One turn's response content → the `AgentMessage` tail: an assistant message
40
+ * holding text/reasoning/tool-call parts, then a tool message holding the
41
+ * resolved tool-result parts. Provider metadata (incl. `thought_signature`)
42
+ * is preserved into `providerOptions`.
43
+ */
44
+ export declare const responseToAgentMessages: (content: ReadonlyArray<unknown>) => ReadonlyArray<AgentMessage>;
45
+ /** Joined text of the assistant text parts in one turn's response. */
46
+ export declare const responseText: (content: ReadonlyArray<unknown>) => string;
47
+ /** Joined text of the reasoning parts (when the provider surfaces them). */
48
+ export declare const responseReasoning: (content: ReadonlyArray<unknown>) => string;
49
+ /** Tool-call summaries; `id` is the key that pairs a call with its result. */
50
+ export declare const responseToolCalls: (content: ReadonlyArray<unknown>) => ReadonlyArray<ToolCallSummary>;
51
+ export interface ToolResultSummary {
52
+ readonly id: string;
53
+ readonly toolName: string;
54
+ readonly ok: boolean;
55
+ readonly result: unknown;
56
+ }
57
+ /** Tool-result summaries; `id` matches the originating call's id. */
58
+ export declare const responseToolResults: (content: ReadonlyArray<unknown>) => ReadonlyArray<ToolResultSummary>;
59
+ /**
60
+ * Token usage from a response's `usage` + the finish part's metadata. The
61
+ * Anthropic fold matters: its `input_tokens` EXCLUDES cache reads/writes
62
+ * (both ride only in the raw usage on the finish part's anthropic metadata),
63
+ * so without folding them back a fully-cached turn reads ~0 input.
64
+ * Gemini/OpenAI already include cached tokens in their prompt counts.
65
+ */
66
+ export declare const extractUsage: (usage: unknown, content: ReadonlyArray<unknown>) => TokenUsage;
67
+ /**
68
+ * Embed the turn usage into the first assistant message's `providerOptions`
69
+ * so it persists with the conversation and can be recovered on resume. Pure —
70
+ * returns a new array with the first assistant message re-built.
71
+ * {@link toPromptMessages} strips this stamp before anything goes back out.
72
+ */
73
+ export declare const withUsageOnAssistant: (messages: ReadonlyArray<AgentMessage>, usage: TokenUsage, model?: Option.Option<string>) => ReadonlyArray<AgentMessage>;
74
+ /** The resolved `provider:modelId` the router stamped onto the finish part. */
75
+ export declare const extractModel: (content: ReadonlyArray<unknown>) => Option.Option<string>;
76
+ /** The turn usage embedded on a persisted assistant message, if any. */
77
+ export declare const assistantUsage: (msg: AgentMessage) => Option.Option<TokenUsage>;
78
+ /** The `provider:modelId` embedded alongside the usage stamp, if any. */
79
+ export declare const assistantModel: (msg: AgentMessage) => Option.Option<string>;