skillscript-runtime 0.2.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 (132) hide show
  1. package/ARCHITECTURE.md +70 -0
  2. package/LICENSE +21 -0
  3. package/README.md +346 -0
  4. package/dist/audit.d.ts +33 -0
  5. package/dist/audit.d.ts.map +1 -0
  6. package/dist/audit.js +76 -0
  7. package/dist/audit.js.map +1 -0
  8. package/dist/bootstrap.d.ts +69 -0
  9. package/dist/bootstrap.d.ts.map +1 -0
  10. package/dist/bootstrap.js +117 -0
  11. package/dist/bootstrap.js.map +1 -0
  12. package/dist/cli.d.ts +3 -0
  13. package/dist/cli.d.ts.map +1 -0
  14. package/dist/cli.js +805 -0
  15. package/dist/cli.js.map +1 -0
  16. package/dist/compile.d.ts +88 -0
  17. package/dist/compile.d.ts.map +1 -0
  18. package/dist/compile.js +544 -0
  19. package/dist/compile.js.map +1 -0
  20. package/dist/connectors/agent-noop.d.ts +23 -0
  21. package/dist/connectors/agent-noop.d.ts.map +1 -0
  22. package/dist/connectors/agent-noop.js +43 -0
  23. package/dist/connectors/agent-noop.js.map +1 -0
  24. package/dist/connectors/agent.d.ts +54 -0
  25. package/dist/connectors/agent.d.ts.map +1 -0
  26. package/dist/connectors/agent.js +21 -0
  27. package/dist/connectors/agent.js.map +1 -0
  28. package/dist/connectors/index.d.ts +13 -0
  29. package/dist/connectors/index.d.ts.map +1 -0
  30. package/dist/connectors/index.js +17 -0
  31. package/dist/connectors/index.js.map +1 -0
  32. package/dist/connectors/local-model.d.ts +41 -0
  33. package/dist/connectors/local-model.d.ts.map +1 -0
  34. package/dist/connectors/local-model.js +106 -0
  35. package/dist/connectors/local-model.js.map +1 -0
  36. package/dist/connectors/mcp.d.ts +22 -0
  37. package/dist/connectors/mcp.d.ts.map +1 -0
  38. package/dist/connectors/mcp.js +31 -0
  39. package/dist/connectors/mcp.js.map +1 -0
  40. package/dist/connectors/memory-store.d.ts +53 -0
  41. package/dist/connectors/memory-store.d.ts.map +1 -0
  42. package/dist/connectors/memory-store.js +169 -0
  43. package/dist/connectors/memory-store.js.map +1 -0
  44. package/dist/connectors/registry.d.ts +74 -0
  45. package/dist/connectors/registry.d.ts.map +1 -0
  46. package/dist/connectors/registry.js +127 -0
  47. package/dist/connectors/registry.js.map +1 -0
  48. package/dist/connectors/skill-store.d.ts +38 -0
  49. package/dist/connectors/skill-store.d.ts.map +1 -0
  50. package/dist/connectors/skill-store.js +314 -0
  51. package/dist/connectors/skill-store.js.map +1 -0
  52. package/dist/connectors/types.d.ts +188 -0
  53. package/dist/connectors/types.d.ts.map +1 -0
  54. package/dist/connectors/types.js +35 -0
  55. package/dist/connectors/types.js.map +1 -0
  56. package/dist/dashboard/server.d.ts +40 -0
  57. package/dist/dashboard/server.d.ts.map +1 -0
  58. package/dist/dashboard/server.js +122 -0
  59. package/dist/dashboard/server.js.map +1 -0
  60. package/dist/dashboard/spa/app.js +375 -0
  61. package/dist/dashboard/spa/index.html +26 -0
  62. package/dist/dashboard/spa/styles.css +99 -0
  63. package/dist/errors.d.ts +111 -0
  64. package/dist/errors.d.ts.map +1 -0
  65. package/dist/errors.js +187 -0
  66. package/dist/errors.js.map +1 -0
  67. package/dist/filters.d.ts +17 -0
  68. package/dist/filters.d.ts.map +1 -0
  69. package/dist/filters.js +40 -0
  70. package/dist/filters.js.map +1 -0
  71. package/dist/index.d.ts +41 -0
  72. package/dist/index.d.ts.map +1 -0
  73. package/dist/index.js +33 -0
  74. package/dist/index.js.map +1 -0
  75. package/dist/lint.d.ts +97 -0
  76. package/dist/lint.d.ts.map +1 -0
  77. package/dist/lint.js +990 -0
  78. package/dist/lint.js.map +1 -0
  79. package/dist/mcp-server.d.ts +93 -0
  80. package/dist/mcp-server.d.ts.map +1 -0
  81. package/dist/mcp-server.js +505 -0
  82. package/dist/mcp-server.js.map +1 -0
  83. package/dist/metrics.d.ts +51 -0
  84. package/dist/metrics.d.ts.map +1 -0
  85. package/dist/metrics.js +107 -0
  86. package/dist/metrics.js.map +1 -0
  87. package/dist/parser.d.ts +160 -0
  88. package/dist/parser.d.ts.map +1 -0
  89. package/dist/parser.js +991 -0
  90. package/dist/parser.js.map +1 -0
  91. package/dist/provenance.d.ts +43 -0
  92. package/dist/provenance.d.ts.map +1 -0
  93. package/dist/provenance.js +58 -0
  94. package/dist/provenance.js.map +1 -0
  95. package/dist/runtime.d.ts +145 -0
  96. package/dist/runtime.d.ts.map +1 -0
  97. package/dist/runtime.js +1071 -0
  98. package/dist/runtime.js.map +1 -0
  99. package/dist/scheduler.d.ts +121 -0
  100. package/dist/scheduler.d.ts.map +1 -0
  101. package/dist/scheduler.js +271 -0
  102. package/dist/scheduler.js.map +1 -0
  103. package/dist/skill-manager.d.ts +121 -0
  104. package/dist/skill-manager.d.ts.map +1 -0
  105. package/dist/skill-manager.js +251 -0
  106. package/dist/skill-manager.js.map +1 -0
  107. package/dist/testing/conformance.d.ts +57 -0
  108. package/dist/testing/conformance.d.ts.map +1 -0
  109. package/dist/testing/conformance.js +365 -0
  110. package/dist/testing/conformance.js.map +1 -0
  111. package/dist/testing/index.d.ts +3 -0
  112. package/dist/testing/index.d.ts.map +1 -0
  113. package/dist/testing/index.js +5 -0
  114. package/dist/testing/index.js.map +1 -0
  115. package/dist/trace.d.ts +141 -0
  116. package/dist/trace.d.ts.map +1 -0
  117. package/dist/trace.js +226 -0
  118. package/dist/trace.js.map +1 -0
  119. package/examples/README.md +56 -0
  120. package/examples/classify-support-ticket.skill.md +30 -0
  121. package/examples/cut-release-tag.skill.md +40 -0
  122. package/examples/doc-qa-with-citations.skill.md +12 -0
  123. package/examples/feedback-sentiment-scan.skill.md +29 -0
  124. package/examples/hello.skill.md +9 -0
  125. package/examples/hello.skill.provenance.json +10 -0
  126. package/examples/morning-brief.skill.md +24 -0
  127. package/examples/programmatic-trace-demo.mjs +89 -0
  128. package/examples/service-health-watch.skill.md +18 -0
  129. package/package.json +100 -0
  130. package/scaffold/config.toml +35 -0
  131. package/scaffold/connectors.json +19 -0
  132. package/scaffold/examples/hello.skill.md +9 -0
@@ -0,0 +1,54 @@
1
+ import type { StaticCapabilities, ManifestInfo } from "./types.js";
2
+ /**
3
+ * Discriminated payload union for `deliver`. The runtime picks `kind`
4
+ * based on the source declaration:
5
+ * - `# Output: prompt-context: <agent>` → `{ kind: "augment", ... }`
6
+ * - `# Output: template: <agent>` → `{ kind: "template", ... }`
7
+ */
8
+ export type DeliveryPayload = {
9
+ kind: "augment";
10
+ content: string;
11
+ format?: "text" | "markdown";
12
+ } | {
13
+ kind: "template";
14
+ prompt: string;
15
+ source_skill?: string;
16
+ };
17
+ export interface DeliveryReceipt {
18
+ /** Unix-ms timestamp the substrate accepted the delivery. */
19
+ delivered_at: number;
20
+ /** Substrate-specific id for callers to correlate later. */
21
+ delivery_id?: string;
22
+ }
23
+ export interface WakeOpts {
24
+ /** Optional preamble to prepend to the wake message. */
25
+ context?: string;
26
+ /** `"immediate"` (default) or a unix-ms timestamp for scheduled wake. */
27
+ when?: "immediate" | number;
28
+ }
29
+ export interface WakeReceipt {
30
+ woken_at: number;
31
+ session_id?: string;
32
+ }
33
+ export interface AgentDescriptor {
34
+ agent_id: string;
35
+ agent_name?: string;
36
+ capabilities?: ReadonlyArray<"deliver" | "wake" | "augment" | "template">;
37
+ }
38
+ export type AgentStatus = "active" | "idle" | "asleep" | "unknown";
39
+ /**
40
+ * The contract. Two primary verbs (deliver + wake), one mandatory
41
+ * discovery method (list_agents), one optional status probe.
42
+ */
43
+ export interface AgentConnector {
44
+ list_agents(): Promise<AgentDescriptor[]>;
45
+ deliver(agent_id: string, payload: DeliveryPayload): Promise<DeliveryReceipt>;
46
+ wake(agent_id: string, opts?: WakeOpts): Promise<WakeReceipt>;
47
+ agent_status?(agent_id: string): Promise<AgentStatus>;
48
+ manifest(): Promise<ManifestInfo>;
49
+ }
50
+ export interface AgentConnectorClass {
51
+ new (...args: never[]): AgentConnector;
52
+ staticCapabilities(): StaticCapabilities;
53
+ }
54
+ //# sourceMappingURL=agent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/connectors/agent.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAEnE;;;;;GAKG;AACH,MAAM,MAAM,eAAe,GACvB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,GAAG,UAAU,CAAA;CAAE,GAClE;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEhE,MAAM,WAAW,eAAe;IAC9B,6DAA6D;IAC7D,YAAY,EAAE,MAAM,CAAC;IACrB,4DAA4D;IAC5D,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,QAAQ;IACvB,wDAAwD;IACxD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yEAAyE;IACzE,IAAI,CAAC,EAAE,WAAW,GAAG,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,aAAa,CAAC,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,UAAU,CAAC,CAAC;CAC3E;AAED,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEnE;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,WAAW,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;IAC1C,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IAC9E,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAC9D,YAAY,CAAC,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IACtD,QAAQ,IAAI,OAAO,CAAC,YAAY,CAAC,CAAC;CACnC;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,GAAG,IAAI,EAAE,KAAK,EAAE,GAAG,cAAc,CAAC;IACvC,kBAAkB,IAAI,kBAAkB,CAAC;CAC1C"}
@@ -0,0 +1,21 @@
1
+ // AgentConnector — the fifth connector contract, added in T7.1 for v0.2.0.
2
+ //
3
+ // Augmenting and Template skill kinds both deliver to a *frontier agent*.
4
+ // The runtime needs a substrate-neutral way to (a) discover which agents
5
+ // are reachable, (b) deliver content into an agent's context, and (c)
6
+ // optionally wake a sleeping agent. AgentConnector covers all three.
7
+ //
8
+ // Substrate examples — the contract is neutral; adopters wire impls:
9
+ //
10
+ // - tmux session: `deliver` via `tmux send-keys` to a pane
11
+ // - webhook: POST to /augment or /template endpoint
12
+ // - file-watch: write to `<path>/augment-<id>.txt`
13
+ // - Slack thread: post to monitored thread
14
+ // - IPC pipe: write to named pipe
15
+ // - AMP memory: write `prompt-context:` memory with recipients (T8)
16
+ //
17
+ // The bundled default is `NoOpAgentConnector` — list_agents returns [],
18
+ // deliver/wake resolve with a warning log. Lets the runtime start cleanly
19
+ // when no agent substrate is wired.
20
+ export {};
21
+ //# sourceMappingURL=agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.js","sourceRoot":"","sources":["../../src/connectors/agent.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,EAAE;AACF,0EAA0E;AAC1E,yEAAyE;AACzE,sEAAsE;AACtE,qEAAqE;AACrE,EAAE;AACF,qEAAqE;AACrE,EAAE;AACF,6DAA6D;AAC7D,2DAA2D;AAC3D,uDAAuD;AACvD,6CAA6C;AAC7C,wCAAwC;AACxC,wEAAwE;AACxE,EAAE;AACF,wEAAwE;AACxE,0EAA0E;AAC1E,oCAAoC"}
@@ -0,0 +1,13 @@
1
+ export type { SkillStore, SkillStoreClass, SkillSource, SkillMeta, SkillStatus, SkillFilter, VersionInfo, MemoryStore, MemoryStoreClass, PortableMemory, QueryFilters, LocalModel, LocalModelClass, McpConnector, McpConnectorClass, McpDispatchCtx, StaticCapabilities, ManifestInfo, ConnectorType, CuratedMemoryField, } from "./types.js";
2
+ export { CURATED_MEMORY_FIELDS } from "./types.js";
3
+ export type { AgentConnector, AgentConnectorClass, AgentDescriptor, AgentStatus, DeliveryPayload, DeliveryReceipt, WakeOpts, WakeReceipt, } from "./agent.js";
4
+ export { Registry } from "./registry.js";
5
+ export { FilesystemSkillStore } from "./skill-store.js";
6
+ export { OllamaLocalModel } from "./local-model.js";
7
+ export type { OllamaConfig } from "./local-model.js";
8
+ export { SqliteMemoryStore } from "./memory-store.js";
9
+ export type { SqliteMemoryStoreConfig } from "./memory-store.js";
10
+ export { CallbackMcpConnector } from "./mcp.js";
11
+ export type { DispatchFn } from "./mcp.js";
12
+ export { NoOpAgentConnector } from "./agent-noop.js";
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/connectors/index.ts"],"names":[],"mappings":"AAUA,YAAY,EACV,UAAU,EACV,eAAe,EACf,WAAW,EACX,SAAS,EACT,WAAW,EACX,WAAW,EACX,WAAW,EACX,WAAW,EACX,gBAAgB,EAChB,cAAc,EACd,YAAY,EACZ,UAAU,EACV,eAAe,EACf,YAAY,EACZ,iBAAiB,EACjB,cAAc,EACd,kBAAkB,EAClB,YAAY,EACZ,aAAa,EACb,kBAAkB,GACnB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAEnD,YAAY,EACV,cAAc,EACd,mBAAmB,EACnB,eAAe,EACf,WAAW,EACX,eAAe,EACf,eAAe,EACf,QAAQ,EACR,WAAW,GACZ,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,YAAY,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,YAAY,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AACjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAChD,YAAY,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,17 @@
1
+ // `skillscript-runtime/connectors` entry point. Adapter authors implementing
2
+ // custom substrate backings import the connector contracts from here:
3
+ //
4
+ // import { type SkillStore, type MemoryStore } from "skillscript-runtime/connectors";
5
+ // class MySkillStore implements SkillStore { ... }
6
+ //
7
+ // Bundled reference implementations (FilesystemSkillStore, OllamaLocalModel,
8
+ // SqliteMemoryStore, CallbackMcpConnector) are also re-exported for embedders
9
+ // who want a one-import wiring path.
10
+ export { CURATED_MEMORY_FIELDS } from "./types.js";
11
+ export { Registry } from "./registry.js";
12
+ export { FilesystemSkillStore } from "./skill-store.js";
13
+ export { OllamaLocalModel } from "./local-model.js";
14
+ export { SqliteMemoryStore } from "./memory-store.js";
15
+ export { CallbackMcpConnector } from "./mcp.js";
16
+ export { NoOpAgentConnector } from "./agent-noop.js";
17
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/connectors/index.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,sEAAsE;AACtE,EAAE;AACF,wFAAwF;AACxF,qDAAqD;AACrD,EAAE;AACF,6EAA6E;AAC7E,8EAA8E;AAC9E,qCAAqC;AAwBrC,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAanD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAEtD,OAAO,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAEhD,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,41 @@
1
+ import type { LocalModel, StaticCapabilities, ManifestInfo } from "./types.js";
2
+ /**
3
+ * Ollama HTTP client. Wraps `POST /api/generate` with the registered model
4
+ * names from the registry instance. The bundled-default registry wires
5
+ * `default` / `gemma2` to `gemma2:9b` and `qwen` to `qwen2.5:7b`, matching
6
+ * the v1 spec.
7
+ *
8
+ * Configuration:
9
+ * - `baseUrl` — Ollama endpoint, defaults to `http://localhost:11434`.
10
+ * - `defaultModelTag` — the Ollama model tag this instance dispatches to
11
+ * (e.g. `gemma2:9b`).
12
+ * - `timeoutMs` — per-call timeout. Default 60s. v1 runtime supports
13
+ * per-op overrides via the `# Timeout:` header (T5 thread).
14
+ */
15
+ export interface OllamaConfig {
16
+ baseUrl?: string;
17
+ defaultModelTag: string;
18
+ timeoutMs?: number;
19
+ }
20
+ export declare class OllamaLocalModel implements LocalModel {
21
+ static staticCapabilities(): StaticCapabilities;
22
+ private readonly baseUrl;
23
+ private readonly defaultModelTag;
24
+ private readonly timeoutMs;
25
+ private manifestCache;
26
+ constructor(config: OllamaConfig);
27
+ run(prompt: string, opts: {
28
+ maxTokens?: number;
29
+ model?: string;
30
+ }): Promise<string>;
31
+ /**
32
+ * Runtime manifest. Queries `/api/tags` for the live model list. Cached
33
+ * until `invalidateManifest()` (or in the future, a `runtime.invalidateConnector()`
34
+ * call) flushes it. Authors don't add new models often enough to justify
35
+ * polling on every dispatch.
36
+ */
37
+ manifest(): Promise<ManifestInfo>;
38
+ invalidateManifest(): void;
39
+ private fetchInstalledModels;
40
+ }
41
+ //# sourceMappingURL=local-model.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-model.d.ts","sourceRoot":"","sources":["../../src/connectors/local-model.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAI/E;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,gBAAiB,YAAW,UAAU;IACjD,MAAM,CAAC,kBAAkB,IAAI,kBAAkB;IAc/C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,aAAa,CAAsD;gBAE/D,MAAM,EAAE,YAAY;IAM1B,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAuCxF;;;;;OAKG;IACG,QAAQ,IAAI,OAAO,CAAC,YAAY,CAAC;IAgBvC,kBAAkB,IAAI,IAAI;YAIZ,oBAAoB;CAcnC"}
@@ -0,0 +1,106 @@
1
+ const CONTRACT_VERSION = "1.0.0";
2
+ export class OllamaLocalModel {
3
+ static staticCapabilities() {
4
+ return {
5
+ connector_type: "local_model",
6
+ implementation: "OllamaLocalModel",
7
+ contract_version: CONTRACT_VERSION,
8
+ features: {
9
+ supports_max_tokens: true,
10
+ supports_timeout: true,
11
+ supports_streaming: false,
12
+ supports_embedding: false,
13
+ },
14
+ };
15
+ }
16
+ baseUrl;
17
+ defaultModelTag;
18
+ timeoutMs;
19
+ manifestCache = null;
20
+ constructor(config) {
21
+ this.baseUrl = config.baseUrl ?? "http://localhost:11434";
22
+ this.defaultModelTag = config.defaultModelTag;
23
+ this.timeoutMs = config.timeoutMs ?? 60_000;
24
+ }
25
+ async run(prompt, opts) {
26
+ // `model` here is the registered name (e.g. `default`, `gemma2`, `qwen`)
27
+ // — but Ollama needs the underlying model tag. The registry resolves
28
+ // the name to this instance before calling us, so we use our own
29
+ // `defaultModelTag`. The `model` param is informational here.
30
+ const body = {
31
+ model: this.defaultModelTag,
32
+ prompt,
33
+ stream: false,
34
+ };
35
+ if (opts.maxTokens !== undefined) {
36
+ body["options"] = { num_predict: opts.maxTokens };
37
+ }
38
+ const controller = new AbortController();
39
+ const t = setTimeout(() => controller.abort(), this.timeoutMs);
40
+ try {
41
+ const resp = await fetch(`${this.baseUrl}/api/generate`, {
42
+ method: "POST",
43
+ headers: { "content-type": "application/json" },
44
+ body: JSON.stringify(body),
45
+ signal: controller.signal,
46
+ });
47
+ if (!resp.ok) {
48
+ const text = await resp.text().catch(() => "");
49
+ throw new Error(`Ollama HTTP ${resp.status}: ${text || resp.statusText}`);
50
+ }
51
+ const data = (await resp.json());
52
+ return data.response ?? "";
53
+ }
54
+ catch (err) {
55
+ if (err.name === "AbortError") {
56
+ throw new Error(`Ollama call timed out after ${this.timeoutMs}ms`);
57
+ }
58
+ throw err;
59
+ }
60
+ finally {
61
+ clearTimeout(t);
62
+ }
63
+ }
64
+ /**
65
+ * Runtime manifest. Queries `/api/tags` for the live model list. Cached
66
+ * until `invalidateManifest()` (or in the future, a `runtime.invalidateConnector()`
67
+ * call) flushes it. Authors don't add new models often enough to justify
68
+ * polling on every dispatch.
69
+ */
70
+ async manifest() {
71
+ if (this.manifestCache === null) {
72
+ const models = await this.fetchInstalledModels().catch(() => []);
73
+ this.manifestCache = { version: "1", models };
74
+ }
75
+ return {
76
+ capabilities_version: this.manifestCache.version,
77
+ manifest: {
78
+ kind: "ollama",
79
+ base_url: this.baseUrl,
80
+ default_model_tag: this.defaultModelTag,
81
+ models_available: this.manifestCache.models,
82
+ },
83
+ };
84
+ }
85
+ invalidateManifest() {
86
+ this.manifestCache = null;
87
+ }
88
+ async fetchInstalledModels() {
89
+ const controller = new AbortController();
90
+ const t = setTimeout(() => controller.abort(), 5_000);
91
+ try {
92
+ const resp = await fetch(`${this.baseUrl}/api/tags`, { signal: controller.signal });
93
+ if (!resp.ok)
94
+ return [];
95
+ const data = (await resp.json());
96
+ return (data.models ?? []).map((m) => m.name ?? "").filter(Boolean);
97
+ }
98
+ catch {
99
+ return [];
100
+ }
101
+ finally {
102
+ clearTimeout(t);
103
+ }
104
+ }
105
+ }
106
+ //# sourceMappingURL=local-model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-model.js","sourceRoot":"","sources":["../../src/connectors/local-model.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import type { McpConnector, McpDispatchCtx, StaticCapabilities, ManifestInfo } from "./types.js";
2
+ /**
3
+ * Callback-based McpConnector. Wraps a user-supplied dispatch function and
4
+ * surfaces it through the McpConnector contract. Useful for:
5
+ *
6
+ * - Test rigs that want to assert on tool calls
7
+ * - Embedders that hand-roll their own MCP transport
8
+ * - The bundled `init` scaffold's commented example
9
+ *
10
+ * T1 baseline ships with no servers wired by default. The v1 spec defers
11
+ * the real HTTP-bridge `McpHttpConnector` to a follow-up — for v1, the
12
+ * minimum is "compile and run a skill, possibly without `$` ops at all."
13
+ */
14
+ export type DispatchFn = (toolName: string, args: Record<string, unknown>, ctxOverrides?: McpDispatchCtx) => Promise<unknown>;
15
+ export declare class CallbackMcpConnector implements McpConnector {
16
+ private readonly dispatchFn;
17
+ static staticCapabilities(): StaticCapabilities;
18
+ constructor(dispatchFn: DispatchFn);
19
+ call(toolName: string, args: Record<string, unknown>, ctxOverrides?: McpDispatchCtx): Promise<unknown>;
20
+ manifest(): Promise<ManifestInfo>;
21
+ }
22
+ //# sourceMappingURL=mcp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../../src/connectors/mcp.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,cAAc,EACd,kBAAkB,EAClB,YAAY,EACb,MAAM,YAAY,CAAC;AAIpB;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,UAAU,GAAG,CACvB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,YAAY,CAAC,EAAE,cAAc,KAC1B,OAAO,CAAC,OAAO,CAAC,CAAC;AAEtB,qBAAa,oBAAqB,YAAW,YAAY;IAc3C,OAAO,CAAC,QAAQ,CAAC,UAAU;IAbvC,MAAM,CAAC,kBAAkB,IAAI,kBAAkB;gBAalB,UAAU,EAAE,UAAU;IAEnD,IAAI,CACF,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,YAAY,CAAC,EAAE,cAAc,GAC5B,OAAO,CAAC,OAAO,CAAC;IAIb,QAAQ,IAAI,OAAO,CAAC,YAAY,CAAC;CAQxC"}
@@ -0,0 +1,31 @@
1
+ const CONTRACT_VERSION = "1.0.0";
2
+ export class CallbackMcpConnector {
3
+ dispatchFn;
4
+ static staticCapabilities() {
5
+ return {
6
+ connector_type: "mcp_connector",
7
+ implementation: "CallbackMcpConnector",
8
+ contract_version: CONTRACT_VERSION,
9
+ features: {
10
+ supports_identity_propagation: true,
11
+ supports_streaming_responses: false,
12
+ supports_batch: false,
13
+ },
14
+ };
15
+ }
16
+ constructor(dispatchFn) {
17
+ this.dispatchFn = dispatchFn;
18
+ }
19
+ call(toolName, args, ctxOverrides) {
20
+ return this.dispatchFn(toolName, args, ctxOverrides);
21
+ }
22
+ async manifest() {
23
+ return {
24
+ capabilities_version: "1",
25
+ manifest: {
26
+ kind: "callback",
27
+ },
28
+ };
29
+ }
30
+ }
31
+ //# sourceMappingURL=mcp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.js","sourceRoot":"","sources":["../../src/connectors/mcp.ts"],"names":[],"mappings":"AAOA,MAAM,gBAAgB,GAAG,OAAO,CAAC;AAoBjC,MAAM,OAAO,oBAAoB;IAcF;IAb7B,MAAM,CAAC,kBAAkB;QACvB,OAAO;YACL,cAAc,EAAE,eAAe;YAC/B,cAAc,EAAE,sBAAsB;YACtC,gBAAgB,EAAE,gBAAgB;YAClC,QAAQ,EAAE;gBACR,6BAA6B,EAAE,IAAI;gBACnC,4BAA4B,EAAE,KAAK;gBACnC,cAAc,EAAE,KAAK;aACtB;SACF,CAAC;IACJ,CAAC;IAED,YAA6B,UAAsB;QAAtB,eAAU,GAAV,UAAU,CAAY;IAAG,CAAC;IAEvD,IAAI,CACF,QAAgB,EAChB,IAA6B,EAC7B,YAA6B;QAE7B,OAAO,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC;IACvD,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,OAAO;YACL,oBAAoB,EAAE,GAAG;YACzB,QAAQ,EAAE;gBACR,IAAI,EAAE,UAAU;aACjB;SACF,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,53 @@
1
+ import type { MemoryStore, PortableMemory, QueryFilters, StaticCapabilities, ManifestInfo } from "./types.js";
2
+ /**
3
+ * SQLite-backed MemoryStore. Schema:
4
+ *
5
+ * memories(
6
+ * id TEXT PRIMARY KEY,
7
+ * summary TEXT NOT NULL,
8
+ * detail TEXT,
9
+ * tags TEXT, -- JSON array
10
+ * created_at INTEGER NOT NULL,
11
+ * metadata TEXT -- JSON object, substrate-specific fields
12
+ * )
13
+ *
14
+ * memories_fts — FTS5 virtual table over summary + detail
15
+ *
16
+ * v1 modes: `fts` (FTS5 keyword), `semantic` and `rerank` reserved (require
17
+ * embedding pipeline, deferred to a follow-up). Filters: domain_tags (substring
18
+ * match), payload_type (top-level metadata field), and arbitrary metadata.*
19
+ * keys.
20
+ *
21
+ * Identity / vault semantics intentionally absent here. Backends that need
22
+ * agent/vault scoping wrap the contract in a separate adapter; the
23
+ * filesystem-default store has no agents and open visibility.
24
+ */
25
+ export interface SqliteMemoryStoreConfig {
26
+ dbPath: string;
27
+ }
28
+ export declare class SqliteMemoryStore implements MemoryStore {
29
+ static staticCapabilities(): StaticCapabilities;
30
+ private readonly db;
31
+ constructor(config: SqliteMemoryStoreConfig);
32
+ private bootstrap;
33
+ query(filters: QueryFilters): Promise<PortableMemory[]>;
34
+ manifest(): Promise<ManifestInfo>;
35
+ /** Helper for tests/seeding — insert a memory. */
36
+ upsert(memory: {
37
+ id: string;
38
+ summary: string;
39
+ detail?: string;
40
+ domain_tags?: string[];
41
+ created_at?: number;
42
+ metadata?: Record<string, unknown>;
43
+ }): void;
44
+ close(): void;
45
+ private rowToMemory;
46
+ /**
47
+ * Strip FTS5 special syntax to safe phrase form. FTS5 errors on bare
48
+ * punctuation; quote each whitespace-separated token to make a phrase
49
+ * search. Authors who want raw FTS5 syntax can pass it pre-quoted.
50
+ */
51
+ private sanitizeFtsQuery;
52
+ }
53
+ //# sourceMappingURL=memory-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-store.d.ts","sourceRoot":"","sources":["../../src/connectors/memory-store.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,WAAW,EACX,cAAc,EACd,YAAY,EACZ,kBAAkB,EAClB,YAAY,EACb,MAAM,YAAY,CAAC;AA4BpB;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,iBAAkB,YAAW,WAAW;IACnD,MAAM,CAAC,kBAAkB,IAAI,kBAAkB;IAiB/C,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAe;gBAEtB,MAAM,EAAE,uBAAuB;IAQ3C,OAAO,CAAC,SAAS;IA0BX,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAmCvD,QAAQ,IAAI,OAAO,CAAC,YAAY,CAAC;IAYvC,kDAAkD;IAClD,MAAM,CAAC,MAAM,EAAE;QACb,EAAE,EAAE,MAAM,CAAC;QACX,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;QACvB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACpC,GAAG,IAAI;IAmBR,KAAK,IAAI,IAAI;IAIb,OAAO,CAAC,WAAW;IAiBnB;;;;OAIG;IACH,OAAO,CAAC,gBAAgB;CAOzB"}
@@ -0,0 +1,169 @@
1
+ import { createRequire } from "node:module";
2
+ import { dirname } from "node:path";
3
+ import { mkdirSync, existsSync } from "node:fs";
4
+ const CONTRACT_VERSION = "1.0.0";
5
+ /**
6
+ * Lazy-load `node:sqlite` at instance construction time, not at module
7
+ * load time. Two reasons:
8
+ * 1. The Vite transformer (used by vitest dev pipeline) strips the
9
+ * `node:` prefix and fails to resolve plain `sqlite`. Lazy-loading
10
+ * via createRequire bypasses Vite entirely.
11
+ * 2. CLI invocations that never touch SQLite (running a no-LocalModel
12
+ * skill, listing skills, etc.) don't pay the ExperimentalWarning
13
+ * cost on every command.
14
+ *
15
+ * Type guarded as `unknown` since we can't import the type without paying
16
+ * the load cost.
17
+ */
18
+ const requireNode = createRequire(import.meta.url);
19
+ function loadDatabaseSync() {
20
+ return requireNode("node:sqlite").DatabaseSync;
21
+ }
22
+ export class SqliteMemoryStore {
23
+ static staticCapabilities() {
24
+ return {
25
+ connector_type: "memory_store",
26
+ implementation: "SqliteMemoryStore",
27
+ contract_version: CONTRACT_VERSION,
28
+ features: {
29
+ supports_writes: true,
30
+ supports_tag_filter: true,
31
+ supports_semantic: false,
32
+ supports_rerank: false,
33
+ supports_thread_status_filter: false,
34
+ supports_pinning: false,
35
+ supports_decay_model: false,
36
+ },
37
+ };
38
+ }
39
+ db;
40
+ constructor(config) {
41
+ const dir = dirname(config.dbPath);
42
+ if (!existsSync(dir))
43
+ mkdirSync(dir, { recursive: true });
44
+ const DatabaseSync = loadDatabaseSync();
45
+ this.db = new DatabaseSync(config.dbPath);
46
+ this.bootstrap();
47
+ }
48
+ bootstrap() {
49
+ this.db.exec(`
50
+ CREATE TABLE IF NOT EXISTS memories (
51
+ id TEXT PRIMARY KEY,
52
+ summary TEXT NOT NULL,
53
+ detail TEXT,
54
+ tags TEXT,
55
+ created_at INTEGER NOT NULL,
56
+ metadata TEXT
57
+ );
58
+ CREATE VIRTUAL TABLE IF NOT EXISTS memories_fts USING fts5(
59
+ summary, detail, content='memories', content_rowid='rowid'
60
+ );
61
+ CREATE TRIGGER IF NOT EXISTS memories_ai AFTER INSERT ON memories BEGIN
62
+ INSERT INTO memories_fts(rowid, summary, detail) VALUES (new.rowid, new.summary, new.detail);
63
+ END;
64
+ CREATE TRIGGER IF NOT EXISTS memories_ad AFTER DELETE ON memories BEGIN
65
+ INSERT INTO memories_fts(memories_fts, rowid, summary, detail) VALUES('delete', old.rowid, old.summary, old.detail);
66
+ END;
67
+ CREATE TRIGGER IF NOT EXISTS memories_au AFTER UPDATE ON memories BEGIN
68
+ INSERT INTO memories_fts(memories_fts, rowid, summary, detail) VALUES('delete', old.rowid, old.summary, old.detail);
69
+ INSERT INTO memories_fts(rowid, summary, detail) VALUES (new.rowid, new.summary, new.detail);
70
+ END;
71
+ `);
72
+ }
73
+ async query(filters) {
74
+ const { query, limit, mode } = filters;
75
+ if (mode !== "fts") {
76
+ throw new Error(`SqliteMemoryStore: mode '${mode}' not supported in T1 baseline. Use 'fts'. ` +
77
+ `Semantic / rerank land alongside the embedding pipeline in a follow-up thread.`);
78
+ }
79
+ if (!query || query.trim() === "") {
80
+ const rows = this.db.prepare("SELECT id, summary, detail, tags, created_at, metadata FROM memories ORDER BY created_at DESC LIMIT $limit").all({ $limit: limit });
81
+ return rows.map((r) => this.rowToMemory(r, undefined));
82
+ }
83
+ const sanitized = this.sanitizeFtsQuery(query);
84
+ const rows = this.db.prepare(`SELECT m.id, m.summary, m.detail, m.tags, m.created_at, m.metadata, bm25(memories_fts) AS score
85
+ FROM memories_fts
86
+ JOIN memories m ON memories_fts.rowid = m.rowid
87
+ WHERE memories_fts MATCH $q
88
+ ORDER BY score
89
+ LIMIT $limit`).all({ $q: sanitized, $limit: limit });
90
+ const results = rows.map((r) => this.rowToMemory(r, r["score"]));
91
+ // Optional substring filter on domain_tags. Stored as a JSON-stringified array.
92
+ if (typeof filters["domain_tags"] === "string" && filters["domain_tags"] !== "") {
93
+ const needle = filters["domain_tags"];
94
+ return results.filter((m) => Array.isArray(m.domain_tags) && m.domain_tags.some((t) => t.includes(needle)));
95
+ }
96
+ return results;
97
+ }
98
+ async manifest() {
99
+ return {
100
+ capabilities_version: "1",
101
+ manifest: {
102
+ kind: "sqlite-fts",
103
+ supported_modes: ["fts"],
104
+ score_range: "unbounded",
105
+ supported_filters: ["domain_tags"],
106
+ },
107
+ };
108
+ }
109
+ /** Helper for tests/seeding — insert a memory. */
110
+ upsert(memory) {
111
+ const tags = memory.domain_tags ? JSON.stringify(memory.domain_tags) : null;
112
+ const metadata = memory.metadata ? JSON.stringify(memory.metadata) : null;
113
+ const createdAt = memory.created_at ?? Math.floor(Date.now() / 1000);
114
+ this.db.prepare(`INSERT INTO memories (id, summary, detail, tags, created_at, metadata)
115
+ VALUES ($id, $summary, $detail, $tags, $createdAt, $metadata)
116
+ ON CONFLICT(id) DO UPDATE SET
117
+ summary = $summary, detail = $detail, tags = $tags, metadata = $metadata`).run({
118
+ $id: memory.id,
119
+ $summary: memory.summary,
120
+ $detail: memory.detail ?? null,
121
+ $tags: tags,
122
+ $createdAt: createdAt,
123
+ $metadata: metadata,
124
+ });
125
+ }
126
+ close() {
127
+ this.db.close();
128
+ }
129
+ rowToMemory(row, score) {
130
+ const tags = typeof row["tags"] === "string" ? safeParseJson(row["tags"]) : null;
131
+ const metadata = typeof row["metadata"] === "string" ? safeParseJson(row["metadata"]) : null;
132
+ const memory = {
133
+ id: row["id"],
134
+ summary: row["summary"],
135
+ created_at: row["created_at"],
136
+ };
137
+ if (typeof row["detail"] === "string")
138
+ memory.detail = row["detail"];
139
+ if (Array.isArray(tags))
140
+ memory.domain_tags = tags;
141
+ if (metadata !== null && typeof metadata === "object") {
142
+ memory.metadata = metadata;
143
+ }
144
+ if (score !== undefined)
145
+ memory.score = score;
146
+ return memory;
147
+ }
148
+ /**
149
+ * Strip FTS5 special syntax to safe phrase form. FTS5 errors on bare
150
+ * punctuation; quote each whitespace-separated token to make a phrase
151
+ * search. Authors who want raw FTS5 syntax can pass it pre-quoted.
152
+ */
153
+ sanitizeFtsQuery(q) {
154
+ return q
155
+ .split(/\s+/)
156
+ .filter((s) => s.length > 0)
157
+ .map((tok) => `"${tok.replace(/"/g, '""')}"`)
158
+ .join(" ");
159
+ }
160
+ }
161
+ function safeParseJson(s) {
162
+ try {
163
+ return JSON.parse(s);
164
+ }
165
+ catch {
166
+ return null;
167
+ }
168
+ }
169
+ //# sourceMappingURL=memory-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-store.js","sourceRoot":"","sources":["../../src/connectors/memory-store.ts"],"names":[],"mappings":"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"}