@theokit/sdk 2.30.0 → 3.0.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.
- package/CHANGELOG.md +10 -0
- package/dist/a2a/index.cjs +8 -1
- package/dist/a2a/index.cjs.map +1 -1
- package/dist/a2a/index.d.cts +1 -1
- package/dist/a2a/index.d.ts +1 -1
- package/dist/a2a/index.js +8 -1
- package/dist/a2a/index.js.map +1 -1
- package/dist/a2a/subagent.d.cts +5 -1
- package/dist/a2a/subagent.d.ts +5 -1
- package/dist/agent-factory.d.ts +5 -20
- package/dist/concurrency.cjs +10 -1
- package/dist/concurrency.cjs.map +1 -1
- package/dist/concurrency.d.cts +7 -1
- package/dist/concurrency.d.ts +7 -1
- package/dist/concurrency.js +10 -1
- package/dist/concurrency.js.map +1 -1
- package/dist/create-skill.d.ts +7 -7
- package/dist/{cron-BNHJywtl.d.ts → cron-BLRe166v.d.ts} +19 -15
- package/dist/{cron-t4oKI2Is.d.cts → cron-C2jWAvlQ.d.cts} +19 -15
- package/dist/cron.d.cts +1 -1
- package/dist/cron.d.ts +1 -1
- package/dist/define-tool.d.ts +12 -1
- package/dist/index.cjs +90 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +60 -114
- package/dist/index.d.ts +60 -114
- package/dist/index.js +79 -1
- package/dist/index.js.map +1 -1
- package/dist/internal/plugins/index.d.cts +1 -1
- package/dist/internal/plugins/index.d.ts +1 -1
- package/dist/internal/plugins/types.d.cts +4 -0
- package/dist/internal/plugins/types.d.ts +4 -0
- package/dist/retry.cjs +10 -1
- package/dist/retry.cjs.map +1 -1
- package/dist/retry.d.cts +12 -1
- package/dist/retry.d.ts +12 -1
- package/dist/retry.js +10 -1
- package/dist/retry.js.map +1 -1
- package/dist/server/auth/index.cjs +8 -1
- package/dist/server/auth/index.cjs.map +1 -1
- package/dist/server/auth/index.d.cts +1 -1
- package/dist/server/auth/index.d.ts +1 -1
- package/dist/server/auth/index.js +8 -1
- package/dist/server/auth/index.js.map +1 -1
- package/dist/server/auth/orchestrator.d.cts +5 -1
- package/dist/server/auth/orchestrator.d.ts +5 -1
- package/dist/subscription/define-subscription.d.cts +5 -0
- package/dist/subscription/define-subscription.d.ts +5 -0
- package/dist/subscription/index.cjs +8 -1
- package/dist/subscription/index.cjs.map +1 -1
- package/dist/subscription/index.d.cts +1 -1
- package/dist/subscription/index.d.ts +1 -1
- package/dist/subscription/index.js +8 -1
- package/dist/subscription/index.js.map +1 -1
- package/package.json +1 -1
package/dist/a2a/subagent.d.cts
CHANGED
|
@@ -115,5 +115,9 @@ export declare class MaxDelegationDepthError extends Error {
|
|
|
115
115
|
readonly code: "max_delegation_depth";
|
|
116
116
|
constructor(currentDepth: number, maxDepth: number);
|
|
117
117
|
}
|
|
118
|
-
|
|
118
|
+
/** SE36 — `SubAgent.create` replaces `defineSubAgent` (ADR 0015). @public */
|
|
119
|
+
export declare class SubAgent {
|
|
120
|
+
private constructor();
|
|
121
|
+
static create(spec: SubAgentSpec, parentDepth?: number): CustomTool;
|
|
122
|
+
}
|
|
119
123
|
export {};
|
package/dist/a2a/subagent.d.ts
CHANGED
|
@@ -115,5 +115,9 @@ export declare class MaxDelegationDepthError extends Error {
|
|
|
115
115
|
readonly code: "max_delegation_depth";
|
|
116
116
|
constructor(currentDepth: number, maxDepth: number);
|
|
117
117
|
}
|
|
118
|
-
|
|
118
|
+
/** SE36 — `SubAgent.create` replaces `defineSubAgent` (ADR 0015). @public */
|
|
119
|
+
export declare class SubAgent {
|
|
120
|
+
private constructor();
|
|
121
|
+
static create(spec: SubAgentSpec, parentDepth?: number): CustomTool;
|
|
122
|
+
}
|
|
119
123
|
export {};
|
package/dist/agent-factory.d.ts
CHANGED
|
@@ -17,23 +17,8 @@ export interface AgentFactory {
|
|
|
17
17
|
*/
|
|
18
18
|
getOrCreate(agentId: string, overrides?: Partial<AgentOptions>): Promise<SDKAgent>;
|
|
19
19
|
}
|
|
20
|
-
/**
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
* Merge rules (ADR D23):
|
|
26
|
-
* - Top-level shallow merge with `overrides` winning.
|
|
27
|
-
* - Deep merge for `local`, `memory`, `cloud` (configuration objects with
|
|
28
|
-
* non-conflicting flat keys).
|
|
29
|
-
* - Total replace for `mcpServers`, `agents`, `tools`, `providers`,
|
|
30
|
-
* `plugins`, `skills`, `context` (collection-shaped).
|
|
31
|
-
* - The function-level `agentId` always wins over both `common.agentId` and
|
|
32
|
-
* `overrides.agentId`.
|
|
33
|
-
*
|
|
34
|
-
* The factory holds `common` by reference — mutating it after construction
|
|
35
|
-
* leaks to subsequent `forSession` calls (documented caveat).
|
|
36
|
-
*
|
|
37
|
-
* @public
|
|
38
|
-
*/
|
|
39
|
-
export declare function createAgentFactory(common: Partial<AgentOptions>): AgentFactory;
|
|
20
|
+
/** SE36 — `AgentFactory.create` replaces `createAgentFactory` (ADR 0015). Merges with the `AgentFactory` interface. @public */
|
|
21
|
+
export declare class AgentFactory {
|
|
22
|
+
private constructor();
|
|
23
|
+
static create(common: Partial<AgentOptions>): AgentFactory;
|
|
24
|
+
}
|
package/dist/concurrency.cjs
CHANGED
|
@@ -80,7 +80,16 @@ async function mapWithConcurrency(items, concurrency, fn, options) {
|
|
|
80
80
|
);
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
-
|
|
83
|
+
// src/concurrency.ts
|
|
84
|
+
var Semaphore = class {
|
|
85
|
+
constructor() {
|
|
86
|
+
}
|
|
87
|
+
static create(permits) {
|
|
88
|
+
return createSemaphore(permits);
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
exports.Semaphore = Semaphore;
|
|
84
93
|
exports.mapWithConcurrency = mapWithConcurrency;
|
|
85
94
|
//# sourceMappingURL=concurrency.cjs.map
|
|
86
95
|
//# sourceMappingURL=concurrency.cjs.map
|
package/dist/concurrency.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors.ts","../src/internal/runtime/concurrency/async-semaphore.ts","../src/internal/runtime/concurrency/map-with-concurrency.ts"],"names":[],"mappings":"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","file":"concurrency.cjs","sourcesContent":["import { defaultRetriableForCode } from \"./internal/default-retriable.js\";\nimport { redactSecrets } from \"./internal/security/redact.js\";\nimport type { RunOperation } from \"./types/run.js\";\n\n/**\n * Finite, machine-readable error codes for provider-originated errors\n * (ADR D66). Consumers can `switch (err.metadata?.code)` exhaustively\n * — adding a new variant is an explicit decision + test coverage.\n *\n * @public\n */\nexport type ErrorCode =\n | \"rate_limit\"\n | \"auth_failed\"\n | \"invalid_request\"\n | \"timeout\"\n | \"server_error\"\n | \"context_too_long\"\n | \"content_filtered\"\n | \"model_unavailable\"\n | \"network\"\n | \"quota_exceeded\"\n | \"unknown\";\n\n/**\n * Codes used by {@link AgentRunError} (Production-Readiness #3, ADR D311).\n *\n * Superset of {@link ErrorCode} extended with codes that do NOT originate\n * from a provider HTTP response:\n *\n * - `quota_exceeded` — billing limit hit (provider 402 or signalled error)\n * - `tool_runtime_error` — custom tool handler threw inside dispatch\n * - `aborted` — caller's `AbortSignal` fired (Phase 4)\n * - `invalid_model` — model id rejected by provider (400 \"model not found\")\n * - `safety_blocked` — provider safety filter blocked req or resp\n * - `provider_unreachable` — DNS/TCP/timeout/5xx at transport boundary\n *\n * The `& {}` tail keeps the literal-union ergonomics (autocomplete) while\n * accepting any string for forward compatibility with constructor calls\n * that pass arbitrary code values (legacy callers).\n *\n * @public\n */\n/**\n * T1.1 — closed literal union for `AgentRunError.code`. The previous\n * `(string & {})` escape hatch let arbitrary strings slip into the type\n * surface and defeated exhaustive `switch (code)` discrimination. This is\n * the canonical closed form. `AgentRunErrorCode` is re-aliased below for\n * source-level back-compat.\n *\n * Adding a new code: append the literal here AND audit every `switch (err.code)`\n * in callers. Type-checker enforces the audit via the `default: assertNever(code)`\n * convention.\n *\n * @public\n */\nexport type KnownAgentRunErrorCode =\n | ErrorCode\n | \"quota_exceeded\"\n | \"tool_runtime_error\"\n | \"aborted\"\n | \"invalid_model\"\n | \"safety_blocked\"\n | \"provider_unreachable\";\n\n/**\n * Back-compat alias of {@link KnownAgentRunErrorCode}. Pre-T1.1 callers that\n * imported `AgentRunErrorCode` keep working; new code SHOULD prefer\n * `KnownAgentRunErrorCode` to make the closed-union intent explicit.\n *\n * @public\n */\nexport type AgentRunErrorCode = KnownAgentRunErrorCode;\n\n/** Snapshot of every known code at runtime — used by the boundary coercer. */\nconst KNOWN_AGENT_RUN_ERROR_CODES = new Set<string>([\n \"rate_limit\",\n \"auth_failed\",\n \"invalid_request\",\n \"timeout\",\n \"server_error\",\n \"context_too_long\",\n \"content_filtered\",\n \"model_unavailable\",\n \"network\",\n \"unknown\",\n \"quota_exceeded\",\n \"tool_runtime_error\",\n \"aborted\",\n \"invalid_model\",\n \"safety_blocked\",\n \"provider_unreachable\",\n]);\n\n/**\n * T1.1 boundary helper — coerce an arbitrary string (typically arriving from\n * a downstream `RunErrorDetail.code` or a deserialized cloud response) into a\n * `KnownAgentRunErrorCode`. Unknown strings collapse to `\"unknown\"` so the\n * closed type contract holds without forcing every caller to switch.\n *\n * @internal\n */\nexport function coerceToKnownAgentRunErrorCode(code: string | undefined): KnownAgentRunErrorCode {\n if (code !== undefined && KNOWN_AGENT_RUN_ERROR_CODES.has(code)) {\n return code as KnownAgentRunErrorCode;\n }\n return \"unknown\";\n}\n\n/**\n * Structured context for errors that originated from a provider HTTP\n * call (ADR D65). Lets callers retry with the right backoff (`retryAfter`),\n * surface actionable diagnostics (`provider`, `endpoint`), and inspect the\n * raw response body when needed (`raw`, capped at ~2KB by the mapper).\n *\n * @public\n */\nexport interface ErrorMetadata {\n /** Provider canonical name (e.g., `\"anthropic\"`, `\"openai\"`, `\"openrouter\"`, `\"gemini\"`). */\n provider: string;\n /** HTTP endpoint that failed (e.g., `\"/v1/messages\"`, `\"/v1/chat/completions\"`). */\n endpoint: string;\n /** Machine-readable error code (finite enum). */\n code: ErrorCode;\n /** HTTP status code if applicable. */\n statusCode?: number;\n /** Seconds to wait before retry, per provider's `retry-after` header (numeric form only). */\n retryAfter?: number;\n /** Raw response body for debugging (truncated to ~2KB by the mapper). */\n raw?: unknown;\n}\n\n/**\n * Base class for all errors thrown by `@theokit/sdk`.\n *\n * Use `isRetryable` to drive retry/backoff logic. `code` and `protoErrorCode`\n * are populated for server-originated errors when available. `metadata`\n * (ADR D65) carries structured `{ provider, endpoint, code, ... }` when\n * the error originated from a provider HTTP call.\n *\n * @public\n */\nexport class TheokitAgentError extends Error {\n override readonly name: string = \"TheokitAgentError\";\n readonly isRetryable: boolean;\n readonly code?: string;\n readonly protoErrorCode?: string;\n readonly metadata?: ErrorMetadata;\n\n constructor(\n message: string,\n options: {\n isRetryable?: boolean;\n code?: string;\n protoErrorCode?: string;\n cause?: unknown;\n metadata?: ErrorMetadata;\n } = {},\n ) {\n super(message, options.cause !== undefined ? { cause: options.cause } : undefined);\n this.isRetryable = options.isRetryable ?? false;\n if (options.code !== undefined) this.code = options.code;\n if (options.protoErrorCode !== undefined) this.protoErrorCode = options.protoErrorCode;\n if (options.metadata !== undefined) this.metadata = options.metadata;\n }\n}\n\n/**\n * Invalid API key, not logged in, insufficient permissions.\n *\n * @public\n */\nexport class AuthenticationError extends TheokitAgentError {\n override readonly name: string = \"AuthenticationError\";\n\n constructor(\n message: string,\n options: { code?: string; cause?: unknown; metadata?: ErrorMetadata } = {},\n ) {\n super(message, { ...options, isRetryable: false });\n }\n}\n\n/**\n * Too many requests or usage limits exceeded.\n *\n * @public\n */\nexport class RateLimitError extends TheokitAgentError {\n override readonly name: string = \"RateLimitError\";\n\n constructor(\n message: string,\n options: { code?: string; cause?: unknown; metadata?: ErrorMetadata } = {},\n ) {\n super(message, { ...options, isRetryable: true });\n }\n}\n\n/**\n * Invalid model, bad request parameters, malformed options.\n *\n * @public\n */\nexport class ConfigurationError extends TheokitAgentError {\n override readonly name: string = \"ConfigurationError\";\n\n constructor(\n message: string,\n options: { code?: string; cause?: unknown; metadata?: ErrorMetadata } = {},\n ) {\n super(message, { ...options, isRetryable: false });\n }\n}\n\n/**\n * Thrown when creating a cloud agent for a repo whose SCM provider is not\n * connected. Use `helpUrl` to point the user at the right reconnect flow.\n *\n * @public\n */\nexport class IntegrationNotConnectedError extends ConfigurationError {\n override readonly name: string = \"IntegrationNotConnectedError\";\n readonly provider: string;\n readonly helpUrl: string;\n\n constructor(\n message: string,\n options: {\n provider: string;\n helpUrl: string;\n code?: string;\n cause?: unknown;\n metadata?: ErrorMetadata;\n },\n ) {\n super(message, options);\n this.provider = options.provider;\n this.helpUrl = options.helpUrl;\n }\n}\n\n/**\n * Service unavailable, timeout, transport-level failure.\n *\n * @public\n */\nexport class NetworkError extends TheokitAgentError {\n override readonly name: string = \"NetworkError\";\n\n constructor(\n message: string,\n options: { code?: string; cause?: unknown; metadata?: ErrorMetadata } = {},\n ) {\n super(message, { ...options, isRetryable: true });\n }\n}\n\n/**\n * Catch-all for unclassified server or runtime errors.\n *\n * @public\n */\nexport class UnknownAgentError extends TheokitAgentError {\n override readonly name: string = \"UnknownAgentError\";\n\n constructor(\n message: string,\n options: { code?: string; cause?: unknown; metadata?: ErrorMetadata } = {},\n ) {\n super(message, { ...options, isRetryable: false });\n }\n}\n\n/**\n * Thrown by `Agent.prompt` (and helpers that go through `run.wait()`) when\n * the option `{ throwOnError: true }` is set and the run terminates with\n * `status: 'error'`. Carries the structured `RunResult.error` fields so\n * callers can `catch` once and branch on `code` / `provider` instead of\n * unwrapping the run.\n *\n * Extends {@link TheokitAgentError} per ADR D65 — no new hierarchy.\n *\n * @example\n * try {\n * await Agent.prompt(msg, { apiKey, model, throwOnError: true });\n * } catch (err) {\n * if (err instanceof AgentRunError && err.code === 'auth_failed') {\n * // bad key\n * }\n * }\n *\n * @public\n */\nexport class AgentRunError extends TheokitAgentError {\n override readonly name: string = \"AgentRunError\";\n readonly provider?: string;\n readonly raw?: string;\n /** Provider's request id (`x-request-id` / `request-id` header). Useful for support tickets. */\n readonly requestId?: string;\n /** SDK conversation id this error was raised inside. */\n readonly conversationId?: string;\n\n constructor(\n message: string,\n options: {\n code: AgentRunErrorCode;\n provider?: string;\n raw?: string;\n requestId?: string;\n conversationId?: string;\n retriable?: boolean;\n cause?: unknown;\n metadata?: ErrorMetadata;\n },\n ) {\n super(message, {\n code: options.code,\n cause: options.cause,\n metadata: options.metadata,\n // D311: most AgentRunErrors are not retriable (auth, validation, abort).\n // Provider mappers (D314) override per-status — explicit `retriable` wins\n // over the implicit default when supplied.\n isRetryable: options.retriable ?? defaultRetriableForCode(options.code),\n });\n if (options.provider !== undefined) this.provider = options.provider;\n if (options.raw !== undefined) this.raw = options.raw;\n if (options.requestId !== undefined) this.requestId = options.requestId;\n if (options.conversationId !== undefined) this.conversationId = options.conversationId;\n }\n\n /**\n * Production-Readiness #3 (ADR D311): alias for `isRetryable` exposed as\n * `retriable` to match the handoff contract. Future v2 will deprecate\n * `isRetryable` in favor of this.\n */\n get retriable(): boolean {\n return this.isRetryable;\n }\n\n /**\n * D312: provider's `Retry-After` header in **milliseconds**. Mappers store\n * the header value (seconds) in `metadata.retryAfter`; this getter\n * multiplies by 1000 so the result composes with `Date.now()`/`setTimeout`.\n *\n * Returns `undefined` when no hint was provided. `0` is a legitimate value\n * — use `=== undefined` check rather than truthy check.\n */\n get retryAfterMs(): number | undefined {\n if (this.metadata?.retryAfter === undefined) return undefined;\n return this.metadata.retryAfter * 1000;\n }\n\n /**\n * D313 + T1.5: alias for `metadata.raw`. Provider response body for\n * debugging. T1.5 wraps the value in `redactSecrets` at the getter\n * boundary so secret-shaped substrings (`sk-...`, Bearer JWTs, etc.) are\n * stripped before reaching the caller. Available but NEVER serialized\n * into `.message` (anti-leak invariant).\n */\n get providerError(): unknown {\n const raw = this.metadata?.raw;\n if (raw === undefined) return undefined;\n if (typeof raw === \"string\") return redactSecrets(raw);\n // Non-string raw (object/buffer) — stringify then redact.\n try {\n return redactSecrets(JSON.stringify(raw));\n } catch {\n return redactSecrets(String(raw));\n }\n }\n\n /**\n * T1.5 — sanitized JSON form. `metadata.raw` is OMITTED by default; opt\n * in via `THEOKIT_DEBUG_RAW_ERRORS=1` to surface the (redacted) raw\n * payload for diagnostics. Every other field stays accessible.\n *\n * The single env-var gate is read each call so operators can toggle at\n * runtime without restarting the process.\n */\n toJSON(): Record<string, unknown> {\n const json: Record<string, unknown> = {\n name: this.name,\n message: this.message,\n isRetryable: this.isRetryable,\n };\n addOptionalFields(json, this);\n const safeMeta = sanitizeMetadata(this.metadata);\n if (safeMeta !== undefined) json.metadata = safeMeta;\n return json;\n }\n}\n\nfunction addOptionalFields(json: Record<string, unknown>, err: AgentRunError): void {\n if (err.code !== undefined) json.code = err.code;\n if (err.provider !== undefined) json.provider = err.provider;\n if (err.requestId !== undefined) json.requestId = err.requestId;\n if (err.conversationId !== undefined) json.conversationId = err.conversationId;\n if (err.raw !== undefined) json.raw = redactSecrets(err.raw);\n}\n\nfunction sanitizeMetadata(meta: ErrorMetadata | undefined): ErrorMetadata | undefined {\n if (meta === undefined) return undefined;\n const { raw, ...rest } = meta;\n const debugRaw = process.env.THEOKIT_DEBUG_RAW_ERRORS === \"1\";\n if (debugRaw && raw !== undefined) {\n const redactedRaw =\n typeof raw === \"string\" ? redactSecrets(raw) : redactSecrets(safeStringify(raw));\n return { ...rest, raw: redactedRaw } as ErrorMetadata;\n }\n return rest as ErrorMetadata;\n}\n\nfunction safeStringify(value: unknown): string {\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n}\n\n/**\n * Is this error transient (worth retrying)?\n *\n * Returns the SDK's own retryability verdict: every {@link TheokitAgentError}\n * subclass computes `isRetryable` at construction (rate-limit / network /\n * credential-pool-exhausted are retryable; auth / configuration / unsupported\n * are not), so this predicate is a single source of truth rather than a\n * re-derivation. Non-SDK errors return `false` conservatively — wrap a foreign\n * error in the appropriate SDK error first if you want it considered transient.\n * It never inspects `err.message`.\n *\n * @example\n * try {\n * await agent.send(message, { throwOnError: true });\n * } catch (err) {\n * if (isTransientError(err)) return retryWithBackoff();\n * throw err;\n * }\n *\n * @public\n */\nexport function isTransientError(err: unknown): boolean {\n return err instanceof TheokitAgentError && err.isRetryable === true;\n}\n\n/**\n * Thrown when a {@link Run} or agent operation is not available on the current\n * runtime. Check first with `run.supports(operation)`.\n *\n * Extends {@link TheokitAgentError} (so error-catching code that branches on\n * `instanceof TheokitAgentError` continues to work) but is never retryable —\n * an unsupported operation will not become supported on retry.\n *\n * @public\n */\nexport class UnsupportedRunOperationError extends TheokitAgentError {\n override readonly name: string = \"UnsupportedRunOperationError\";\n readonly operation: RunOperation;\n\n constructor(\n message: string,\n operation: RunOperation,\n options: { code?: string; cause?: unknown } = {},\n ) {\n super(message, {\n ...options,\n isRetryable: false,\n code: options.code ?? \"unsupported_run_operation\",\n });\n this.operation = operation;\n }\n}\n\n/**\n * Thrown when every credential in a per-provider pool is in cooldown\n * and no healthy key is available (ADR D133). The caller's\n * {@link import(\"./internal/llm/fallback-client.js\").FallbackLlmClient}\n * catches this and tries the next provider in the fallback chain.\n *\n * `metadata.nextRetryAt` (epoch ms) tells callers when the soonest\n * pool entry resumes — useful for manual retry scheduling.\n *\n * @public\n */\nexport class CredentialPoolExhaustedError extends TheokitAgentError {\n override readonly name: string = \"CredentialPoolExhaustedError\";\n readonly provider: string;\n readonly nextRetryAt: number | undefined;\n\n constructor(\n message: string,\n options: {\n provider: string;\n nextRetryAt?: number;\n code?: string;\n cause?: unknown;\n metadata?: ErrorMetadata;\n },\n ) {\n super(message, {\n ...options,\n isRetryable: true,\n code: options.code ?? \"credential_pool_exhausted\",\n });\n this.provider = options.provider;\n this.nextRetryAt = options.nextRetryAt;\n }\n}\n\n/**\n * Finite error codes specific to memory adapter operations (ADR D141).\n *\n * @public\n */\nexport type MemoryAdapterErrorCode =\n | \"auth_failed\"\n | \"rate_limited\"\n | \"not_found\"\n | \"network\"\n | \"invalid_input\"\n | \"unknown\";\n\n/**\n * Error raised by `@theokit-memory-*` adapters. Carries `adapterId`\n * so callers can branch on which provider failed (ADR D141).\n *\n * @public\n */\nexport class MemoryAdapterError extends TheokitAgentError {\n override readonly name: string = \"MemoryAdapterError\";\n readonly adapterId: string;\n\n constructor(\n message: string,\n options: {\n adapterId: string;\n code: MemoryAdapterErrorCode;\n cause?: unknown;\n metadata?: ErrorMetadata;\n },\n ) {\n super(message, {\n isRetryable: options.code === \"rate_limited\" || options.code === \"network\",\n code: options.code,\n ...(options.cause !== undefined ? { cause: options.cause } : {}),\n ...(options.metadata !== undefined ? { metadata: options.metadata } : {}),\n });\n this.adapterId = options.adapterId;\n }\n}\n\n/**\n * Thrown when a user-supplied task ID violates the grammar\n * `^[a-z0-9][a-z0-9_-]*$` (D368) OR starts with a reserved adapter\n * prefix (`wf-` / `b-` / `cron-`, EC-5).\n *\n * @public\n */\nexport class InvalidTaskIdError extends TheokitAgentError {\n override readonly name: string = \"InvalidTaskIdError\";\n readonly taskId: string;\n\n constructor(message: string, taskId: string, options: { cause?: unknown } = {}) {\n super(message, {\n ...options,\n isRetryable: false,\n code: \"invalid_task_id\",\n });\n this.taskId = taskId;\n }\n}\n\n/**\n * Thrown when `Task.subscribe(id)` is called for a task that has been\n * evicted, never submitted, or evicted after retention (D373).\n *\n * @public\n */\nexport class TaskNotFoundError extends TheokitAgentError {\n override readonly name: string = \"TaskNotFoundError\";\n readonly taskId: string;\n\n constructor(taskId: string, options: { cause?: unknown } = {}) {\n super(`Task not found: ${taskId}`, {\n ...options,\n isRetryable: false,\n code: \"task_not_found\",\n });\n this.taskId = taskId;\n }\n}\n\n/**\n * Thrown when `CloudAgent` is asked to wrap a task (D370). Cloud\n * task observability is deferred until Theo PaaS GA.\n *\n * @public\n */\nexport class UnsupportedTaskOperationError extends TheokitAgentError {\n override readonly name: string = \"UnsupportedTaskOperationError\";\n readonly operation: string;\n\n constructor(operation: string, options: { cause?: unknown } = {}) {\n super(\n `Task operation \"${operation}\" is not supported on CloudAgent (pre-release; see ADR D370)`,\n {\n ...options,\n isRetryable: false,\n code: \"task_op_unsupported\",\n },\n );\n this.operation = operation;\n }\n}\n\n/**\n * Thrown by `Budget` enforcement (ADR D386) when a `mode: \"block\"`\n * budget would be exceeded by the upcoming LLM call. Caller pega\n * tipado para retry-after-window-reset or surface to the user.\n *\n * @public\n */\nexport class BudgetExceededError extends TheokitAgentError {\n override readonly name: string = \"BudgetExceededError\";\n readonly budgetName: string;\n readonly window: import(\"./types/budget.js\").BudgetWindow;\n readonly spentUsd: number;\n readonly limitUsd: number;\n readonly mode: import(\"./types/budget.js\").BudgetMode;\n\n constructor(args: {\n budgetName: string;\n window: import(\"./types/budget.js\").BudgetWindow;\n spentUsd: number;\n limitUsd: number;\n mode: import(\"./types/budget.js\").BudgetMode;\n cause?: unknown;\n }) {\n super(\n `Budget \"${args.budgetName}\" exceeded for window ${args.window}: spent $${args.spentUsd.toFixed(4)} > limit $${args.limitUsd.toFixed(4)}`,\n {\n ...(args.cause !== undefined ? { cause: args.cause } : {}),\n isRetryable: false,\n code: \"budget_exceeded\",\n },\n );\n this.budgetName = args.budgetName;\n this.window = args.window;\n this.spentUsd = args.spentUsd;\n this.limitUsd = args.limitUsd;\n this.mode = args.mode;\n }\n}\n\n/**\n * Thrown when `CloudAgent.send({ budget })` is invoked (D388). Cloud\n * budget surface waits for Theo PaaS GA.\n *\n * @public\n */\n/**\n * T1.6 — Thrown when a consumer calls `agent.send()` or any method\n * on an agent that has already been `dispose()`d. Pre-T1.6 this was\n * a generic `new Error(\"Agent has been disposed\")` — consumers\n * couldn't catch it without string-matching the message.\n *\n * @public\n */\nexport class AgentDisposedError extends TheokitAgentError {\n override readonly name: string = \"AgentDisposedError\";\n readonly agentId: string;\n\n constructor(agentId: string) {\n super(`Agent \"${agentId}\" has been disposed. Create a new agent or use Agent.resume().`, {\n isRetryable: false,\n code: \"agent_disposed\",\n });\n this.agentId = agentId;\n }\n}\n\nexport class UnsupportedBudgetOperationError extends TheokitAgentError {\n override readonly name: string = \"UnsupportedBudgetOperationError\";\n readonly operation: string;\n\n constructor(operation: string, options: { cause?: unknown } = {}) {\n super(\n `Budget operation \"${operation}\" is not supported on CloudAgent (pre-release; see ADR D388)`,\n {\n ...options,\n isRetryable: false,\n code: \"budget_op_unsupported\",\n },\n );\n this.operation = operation;\n }\n}\n","/**\n * Async-aware counting semaphore (ADR D135).\n *\n * N-permit gate for cooperative concurrency control inside a single\n * Node process. Used by `Agent.batch` to bound parallel agent count\n * without pulling in `p-limit` or `p-queue` (~30 LoC in-house).\n *\n * Contract: `acquire()` returns a release function. Caller MUST call\n * release exactly once when done — typically in a `finally` block.\n * Release is idempotent (multiple calls are no-ops after the first)\n * for defense against caller bugs, but leaking the release function\n * permanently consumes one permit (EC-G — caller responsibility).\n *\n * @internal\n */\n\nimport { ConfigurationError } from \"../../../errors.js\";\n\nexport interface AsyncSemaphore {\n /** Acquire a permit. Returns the release function (call once). */\n acquire(): Promise<() => void>;\n /** Permits currently held in flight. */\n inFlight(): number;\n /** Total: in-flight + queued waiters. */\n pending(): number;\n}\n\nexport function createSemaphore(permits: number): AsyncSemaphore {\n if (!Number.isInteger(permits) || permits < 1) {\n throw new ConfigurationError(\n `async-semaphore: permits must be a positive integer, got ${permits}`,\n { code: \"invalid_concurrency\" },\n );\n }\n let active = 0;\n const queue: Array<() => void> = [];\n\n function tryGrant(): void {\n if (active < permits && queue.length > 0) {\n const resolve = queue.shift();\n if (resolve !== undefined) {\n active += 1;\n resolve();\n }\n }\n }\n\n return {\n inFlight: () => active,\n pending: () => queue.length + active,\n async acquire() {\n await new Promise<void>((resolve) => {\n queue.push(resolve);\n tryGrant();\n });\n let released = false;\n return () => {\n if (released) return;\n released = true;\n active -= 1;\n tryGrant();\n };\n },\n };\n}\n","/**\n * Ordered, bounded-concurrency parallel map (plan m0-foundation-expose-primitives, M0-2).\n *\n * Runs `fn` over `items` with at most `concurrency` invocations in flight at\n * once, preserving input order in the result array. Fail-fast: rejects with the\n * first error a task throws (matching the in-house `boundedParallel`/`runBatches`\n * clones this consolidates). Backed by the in-house {@link createSemaphore}\n * (ADR D135 — no `p-limit`/`p-map` dependency).\n *\n * @internal — public via `@theokit/sdk/concurrency`\n */\n\nimport { createSemaphore } from \"./async-semaphore.js\";\n\nconst NEVER_ABORT: AbortSignal = new AbortController().signal;\n\n/**\n * Map `fn` over `items` with bounded concurrency, preserving order.\n *\n * @param items - inputs to process\n * @param concurrency - max in-flight invocations (positive integer; validated)\n * @param fn - async mapper; receives the item, its index, and an abort signal\n * @param options.signal - optional abort signal; once aborted, no new `fn`\n * invocation is started (in-flight ones are not force-cancelled)\n * @returns results in the same order as `items`\n * @throws ConfigurationError when `concurrency` is not a positive integer\n *\n * @example\n * await mapWithConcurrency([1, 2, 3], 2, async (n) => n * 2); // [2, 4, 6]\n */\nexport async function mapWithConcurrency<T, R>(\n items: ReadonlyArray<T>,\n concurrency: number,\n fn: (item: T, index: number, signal: AbortSignal) => Promise<R>,\n options?: { signal?: AbortSignal },\n): Promise<R[]> {\n const semaphore = createSemaphore(concurrency);\n const signal = options?.signal ?? NEVER_ABORT;\n return Promise.all(\n items.map(async (item, index) => {\n const release = await semaphore.acquire();\n try {\n if (signal.aborted) {\n throw signal.reason instanceof Error\n ? signal.reason\n : new Error(\"mapWithConcurrency: aborted\");\n }\n return await fn(item, index, signal);\n } finally {\n release();\n }\n }),\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/internal/runtime/concurrency/async-semaphore.ts","../src/internal/runtime/concurrency/map-with-concurrency.ts","../src/concurrency.ts"],"names":[],"mappings":"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","file":"concurrency.cjs","sourcesContent":["import { defaultRetriableForCode } from \"./internal/default-retriable.js\";\nimport { redactSecrets } from \"./internal/security/redact.js\";\nimport type { RunOperation } from \"./types/run.js\";\n\n/**\n * Finite, machine-readable error codes for provider-originated errors\n * (ADR D66). Consumers can `switch (err.metadata?.code)` exhaustively\n * — adding a new variant is an explicit decision + test coverage.\n *\n * @public\n */\nexport type ErrorCode =\n | \"rate_limit\"\n | \"auth_failed\"\n | \"invalid_request\"\n | \"timeout\"\n | \"server_error\"\n | \"context_too_long\"\n | \"content_filtered\"\n | \"model_unavailable\"\n | \"network\"\n | \"quota_exceeded\"\n | \"unknown\";\n\n/**\n * Codes used by {@link AgentRunError} (Production-Readiness #3, ADR D311).\n *\n * Superset of {@link ErrorCode} extended with codes that do NOT originate\n * from a provider HTTP response:\n *\n * - `quota_exceeded` — billing limit hit (provider 402 or signalled error)\n * - `tool_runtime_error` — custom tool handler threw inside dispatch\n * - `aborted` — caller's `AbortSignal` fired (Phase 4)\n * - `invalid_model` — model id rejected by provider (400 \"model not found\")\n * - `safety_blocked` — provider safety filter blocked req or resp\n * - `provider_unreachable` — DNS/TCP/timeout/5xx at transport boundary\n *\n * The `& {}` tail keeps the literal-union ergonomics (autocomplete) while\n * accepting any string for forward compatibility with constructor calls\n * that pass arbitrary code values (legacy callers).\n *\n * @public\n */\n/**\n * T1.1 — closed literal union for `AgentRunError.code`. The previous\n * `(string & {})` escape hatch let arbitrary strings slip into the type\n * surface and defeated exhaustive `switch (code)` discrimination. This is\n * the canonical closed form. `AgentRunErrorCode` is re-aliased below for\n * source-level back-compat.\n *\n * Adding a new code: append the literal here AND audit every `switch (err.code)`\n * in callers. Type-checker enforces the audit via the `default: assertNever(code)`\n * convention.\n *\n * @public\n */\nexport type KnownAgentRunErrorCode =\n | ErrorCode\n | \"quota_exceeded\"\n | \"tool_runtime_error\"\n | \"aborted\"\n | \"invalid_model\"\n | \"safety_blocked\"\n | \"provider_unreachable\";\n\n/**\n * Back-compat alias of {@link KnownAgentRunErrorCode}. Pre-T1.1 callers that\n * imported `AgentRunErrorCode` keep working; new code SHOULD prefer\n * `KnownAgentRunErrorCode` to make the closed-union intent explicit.\n *\n * @public\n */\nexport type AgentRunErrorCode = KnownAgentRunErrorCode;\n\n/** Snapshot of every known code at runtime — used by the boundary coercer. */\nconst KNOWN_AGENT_RUN_ERROR_CODES = new Set<string>([\n \"rate_limit\",\n \"auth_failed\",\n \"invalid_request\",\n \"timeout\",\n \"server_error\",\n \"context_too_long\",\n \"content_filtered\",\n \"model_unavailable\",\n \"network\",\n \"unknown\",\n \"quota_exceeded\",\n \"tool_runtime_error\",\n \"aborted\",\n \"invalid_model\",\n \"safety_blocked\",\n \"provider_unreachable\",\n]);\n\n/**\n * T1.1 boundary helper — coerce an arbitrary string (typically arriving from\n * a downstream `RunErrorDetail.code` or a deserialized cloud response) into a\n * `KnownAgentRunErrorCode`. Unknown strings collapse to `\"unknown\"` so the\n * closed type contract holds without forcing every caller to switch.\n *\n * @internal\n */\nexport function coerceToKnownAgentRunErrorCode(code: string | undefined): KnownAgentRunErrorCode {\n if (code !== undefined && KNOWN_AGENT_RUN_ERROR_CODES.has(code)) {\n return code as KnownAgentRunErrorCode;\n }\n return \"unknown\";\n}\n\n/**\n * Structured context for errors that originated from a provider HTTP\n * call (ADR D65). Lets callers retry with the right backoff (`retryAfter`),\n * surface actionable diagnostics (`provider`, `endpoint`), and inspect the\n * raw response body when needed (`raw`, capped at ~2KB by the mapper).\n *\n * @public\n */\nexport interface ErrorMetadata {\n /** Provider canonical name (e.g., `\"anthropic\"`, `\"openai\"`, `\"openrouter\"`, `\"gemini\"`). */\n provider: string;\n /** HTTP endpoint that failed (e.g., `\"/v1/messages\"`, `\"/v1/chat/completions\"`). */\n endpoint: string;\n /** Machine-readable error code (finite enum). */\n code: ErrorCode;\n /** HTTP status code if applicable. */\n statusCode?: number;\n /** Seconds to wait before retry, per provider's `retry-after` header (numeric form only). */\n retryAfter?: number;\n /** Raw response body for debugging (truncated to ~2KB by the mapper). */\n raw?: unknown;\n}\n\n/**\n * Base class for all errors thrown by `@theokit/sdk`.\n *\n * Use `isRetryable` to drive retry/backoff logic. `code` and `protoErrorCode`\n * are populated for server-originated errors when available. `metadata`\n * (ADR D65) carries structured `{ provider, endpoint, code, ... }` when\n * the error originated from a provider HTTP call.\n *\n * @public\n */\nexport class TheokitAgentError extends Error {\n override readonly name: string = \"TheokitAgentError\";\n readonly isRetryable: boolean;\n readonly code?: string;\n readonly protoErrorCode?: string;\n readonly metadata?: ErrorMetadata;\n\n constructor(\n message: string,\n options: {\n isRetryable?: boolean;\n code?: string;\n protoErrorCode?: string;\n cause?: unknown;\n metadata?: ErrorMetadata;\n } = {},\n ) {\n super(message, options.cause !== undefined ? { cause: options.cause } : undefined);\n this.isRetryable = options.isRetryable ?? false;\n if (options.code !== undefined) this.code = options.code;\n if (options.protoErrorCode !== undefined) this.protoErrorCode = options.protoErrorCode;\n if (options.metadata !== undefined) this.metadata = options.metadata;\n }\n}\n\n/**\n * Invalid API key, not logged in, insufficient permissions.\n *\n * @public\n */\nexport class AuthenticationError extends TheokitAgentError {\n override readonly name: string = \"AuthenticationError\";\n\n constructor(\n message: string,\n options: { code?: string; cause?: unknown; metadata?: ErrorMetadata } = {},\n ) {\n super(message, { ...options, isRetryable: false });\n }\n}\n\n/**\n * Too many requests or usage limits exceeded.\n *\n * @public\n */\nexport class RateLimitError extends TheokitAgentError {\n override readonly name: string = \"RateLimitError\";\n\n constructor(\n message: string,\n options: { code?: string; cause?: unknown; metadata?: ErrorMetadata } = {},\n ) {\n super(message, { ...options, isRetryable: true });\n }\n}\n\n/**\n * Invalid model, bad request parameters, malformed options.\n *\n * @public\n */\nexport class ConfigurationError extends TheokitAgentError {\n override readonly name: string = \"ConfigurationError\";\n\n constructor(\n message: string,\n options: { code?: string; cause?: unknown; metadata?: ErrorMetadata } = {},\n ) {\n super(message, { ...options, isRetryable: false });\n }\n}\n\n/**\n * Thrown when creating a cloud agent for a repo whose SCM provider is not\n * connected. Use `helpUrl` to point the user at the right reconnect flow.\n *\n * @public\n */\nexport class IntegrationNotConnectedError extends ConfigurationError {\n override readonly name: string = \"IntegrationNotConnectedError\";\n readonly provider: string;\n readonly helpUrl: string;\n\n constructor(\n message: string,\n options: {\n provider: string;\n helpUrl: string;\n code?: string;\n cause?: unknown;\n metadata?: ErrorMetadata;\n },\n ) {\n super(message, options);\n this.provider = options.provider;\n this.helpUrl = options.helpUrl;\n }\n}\n\n/**\n * Service unavailable, timeout, transport-level failure.\n *\n * @public\n */\nexport class NetworkError extends TheokitAgentError {\n override readonly name: string = \"NetworkError\";\n\n constructor(\n message: string,\n options: { code?: string; cause?: unknown; metadata?: ErrorMetadata } = {},\n ) {\n super(message, { ...options, isRetryable: true });\n }\n}\n\n/**\n * Catch-all for unclassified server or runtime errors.\n *\n * @public\n */\nexport class UnknownAgentError extends TheokitAgentError {\n override readonly name: string = \"UnknownAgentError\";\n\n constructor(\n message: string,\n options: { code?: string; cause?: unknown; metadata?: ErrorMetadata } = {},\n ) {\n super(message, { ...options, isRetryable: false });\n }\n}\n\n/**\n * Thrown by `Agent.prompt` (and helpers that go through `run.wait()`) when\n * the option `{ throwOnError: true }` is set and the run terminates with\n * `status: 'error'`. Carries the structured `RunResult.error` fields so\n * callers can `catch` once and branch on `code` / `provider` instead of\n * unwrapping the run.\n *\n * Extends {@link TheokitAgentError} per ADR D65 — no new hierarchy.\n *\n * @example\n * try {\n * await Agent.prompt(msg, { apiKey, model, throwOnError: true });\n * } catch (err) {\n * if (err instanceof AgentRunError && err.code === 'auth_failed') {\n * // bad key\n * }\n * }\n *\n * @public\n */\nexport class AgentRunError extends TheokitAgentError {\n override readonly name: string = \"AgentRunError\";\n readonly provider?: string;\n readonly raw?: string;\n /** Provider's request id (`x-request-id` / `request-id` header). Useful for support tickets. */\n readonly requestId?: string;\n /** SDK conversation id this error was raised inside. */\n readonly conversationId?: string;\n\n constructor(\n message: string,\n options: {\n code: AgentRunErrorCode;\n provider?: string;\n raw?: string;\n requestId?: string;\n conversationId?: string;\n retriable?: boolean;\n cause?: unknown;\n metadata?: ErrorMetadata;\n },\n ) {\n super(message, {\n code: options.code,\n cause: options.cause,\n metadata: options.metadata,\n // D311: most AgentRunErrors are not retriable (auth, validation, abort).\n // Provider mappers (D314) override per-status — explicit `retriable` wins\n // over the implicit default when supplied.\n isRetryable: options.retriable ?? defaultRetriableForCode(options.code),\n });\n if (options.provider !== undefined) this.provider = options.provider;\n if (options.raw !== undefined) this.raw = options.raw;\n if (options.requestId !== undefined) this.requestId = options.requestId;\n if (options.conversationId !== undefined) this.conversationId = options.conversationId;\n }\n\n /**\n * Production-Readiness #3 (ADR D311): alias for `isRetryable` exposed as\n * `retriable` to match the handoff contract. Future v2 will deprecate\n * `isRetryable` in favor of this.\n */\n get retriable(): boolean {\n return this.isRetryable;\n }\n\n /**\n * D312: provider's `Retry-After` header in **milliseconds**. Mappers store\n * the header value (seconds) in `metadata.retryAfter`; this getter\n * multiplies by 1000 so the result composes with `Date.now()`/`setTimeout`.\n *\n * Returns `undefined` when no hint was provided. `0` is a legitimate value\n * — use `=== undefined` check rather than truthy check.\n */\n get retryAfterMs(): number | undefined {\n if (this.metadata?.retryAfter === undefined) return undefined;\n return this.metadata.retryAfter * 1000;\n }\n\n /**\n * D313 + T1.5: alias for `metadata.raw`. Provider response body for\n * debugging. T1.5 wraps the value in `redactSecrets` at the getter\n * boundary so secret-shaped substrings (`sk-...`, Bearer JWTs, etc.) are\n * stripped before reaching the caller. Available but NEVER serialized\n * into `.message` (anti-leak invariant).\n */\n get providerError(): unknown {\n const raw = this.metadata?.raw;\n if (raw === undefined) return undefined;\n if (typeof raw === \"string\") return redactSecrets(raw);\n // Non-string raw (object/buffer) — stringify then redact.\n try {\n return redactSecrets(JSON.stringify(raw));\n } catch {\n return redactSecrets(String(raw));\n }\n }\n\n /**\n * T1.5 — sanitized JSON form. `metadata.raw` is OMITTED by default; opt\n * in via `THEOKIT_DEBUG_RAW_ERRORS=1` to surface the (redacted) raw\n * payload for diagnostics. Every other field stays accessible.\n *\n * The single env-var gate is read each call so operators can toggle at\n * runtime without restarting the process.\n */\n toJSON(): Record<string, unknown> {\n const json: Record<string, unknown> = {\n name: this.name,\n message: this.message,\n isRetryable: this.isRetryable,\n };\n addOptionalFields(json, this);\n const safeMeta = sanitizeMetadata(this.metadata);\n if (safeMeta !== undefined) json.metadata = safeMeta;\n return json;\n }\n}\n\nfunction addOptionalFields(json: Record<string, unknown>, err: AgentRunError): void {\n if (err.code !== undefined) json.code = err.code;\n if (err.provider !== undefined) json.provider = err.provider;\n if (err.requestId !== undefined) json.requestId = err.requestId;\n if (err.conversationId !== undefined) json.conversationId = err.conversationId;\n if (err.raw !== undefined) json.raw = redactSecrets(err.raw);\n}\n\nfunction sanitizeMetadata(meta: ErrorMetadata | undefined): ErrorMetadata | undefined {\n if (meta === undefined) return undefined;\n const { raw, ...rest } = meta;\n const debugRaw = process.env.THEOKIT_DEBUG_RAW_ERRORS === \"1\";\n if (debugRaw && raw !== undefined) {\n const redactedRaw =\n typeof raw === \"string\" ? redactSecrets(raw) : redactSecrets(safeStringify(raw));\n return { ...rest, raw: redactedRaw } as ErrorMetadata;\n }\n return rest as ErrorMetadata;\n}\n\nfunction safeStringify(value: unknown): string {\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n}\n\n/**\n * Is this error transient (worth retrying)?\n *\n * Returns the SDK's own retryability verdict: every {@link TheokitAgentError}\n * subclass computes `isRetryable` at construction (rate-limit / network /\n * credential-pool-exhausted are retryable; auth / configuration / unsupported\n * are not), so this predicate is a single source of truth rather than a\n * re-derivation. Non-SDK errors return `false` conservatively — wrap a foreign\n * error in the appropriate SDK error first if you want it considered transient.\n * It never inspects `err.message`.\n *\n * @example\n * try {\n * await agent.send(message, { throwOnError: true });\n * } catch (err) {\n * if (isTransientError(err)) return retryWithBackoff();\n * throw err;\n * }\n *\n * @public\n */\nexport function isTransientError(err: unknown): boolean {\n return err instanceof TheokitAgentError && err.isRetryable === true;\n}\n\n/**\n * Thrown when a {@link Run} or agent operation is not available on the current\n * runtime. Check first with `run.supports(operation)`.\n *\n * Extends {@link TheokitAgentError} (so error-catching code that branches on\n * `instanceof TheokitAgentError` continues to work) but is never retryable —\n * an unsupported operation will not become supported on retry.\n *\n * @public\n */\nexport class UnsupportedRunOperationError extends TheokitAgentError {\n override readonly name: string = \"UnsupportedRunOperationError\";\n readonly operation: RunOperation;\n\n constructor(\n message: string,\n operation: RunOperation,\n options: { code?: string; cause?: unknown } = {},\n ) {\n super(message, {\n ...options,\n isRetryable: false,\n code: options.code ?? \"unsupported_run_operation\",\n });\n this.operation = operation;\n }\n}\n\n/**\n * Thrown when every credential in a per-provider pool is in cooldown\n * and no healthy key is available (ADR D133). The caller's\n * {@link import(\"./internal/llm/fallback-client.js\").FallbackLlmClient}\n * catches this and tries the next provider in the fallback chain.\n *\n * `metadata.nextRetryAt` (epoch ms) tells callers when the soonest\n * pool entry resumes — useful for manual retry scheduling.\n *\n * @public\n */\nexport class CredentialPoolExhaustedError extends TheokitAgentError {\n override readonly name: string = \"CredentialPoolExhaustedError\";\n readonly provider: string;\n readonly nextRetryAt: number | undefined;\n\n constructor(\n message: string,\n options: {\n provider: string;\n nextRetryAt?: number;\n code?: string;\n cause?: unknown;\n metadata?: ErrorMetadata;\n },\n ) {\n super(message, {\n ...options,\n isRetryable: true,\n code: options.code ?? \"credential_pool_exhausted\",\n });\n this.provider = options.provider;\n this.nextRetryAt = options.nextRetryAt;\n }\n}\n\n/**\n * Finite error codes specific to memory adapter operations (ADR D141).\n *\n * @public\n */\nexport type MemoryAdapterErrorCode =\n | \"auth_failed\"\n | \"rate_limited\"\n | \"not_found\"\n | \"network\"\n | \"invalid_input\"\n | \"unknown\";\n\n/**\n * Error raised by `@theokit-memory-*` adapters. Carries `adapterId`\n * so callers can branch on which provider failed (ADR D141).\n *\n * @public\n */\nexport class MemoryAdapterError extends TheokitAgentError {\n override readonly name: string = \"MemoryAdapterError\";\n readonly adapterId: string;\n\n constructor(\n message: string,\n options: {\n adapterId: string;\n code: MemoryAdapterErrorCode;\n cause?: unknown;\n metadata?: ErrorMetadata;\n },\n ) {\n super(message, {\n isRetryable: options.code === \"rate_limited\" || options.code === \"network\",\n code: options.code,\n ...(options.cause !== undefined ? { cause: options.cause } : {}),\n ...(options.metadata !== undefined ? { metadata: options.metadata } : {}),\n });\n this.adapterId = options.adapterId;\n }\n}\n\n/**\n * Thrown when a user-supplied task ID violates the grammar\n * `^[a-z0-9][a-z0-9_-]*$` (D368) OR starts with a reserved adapter\n * prefix (`wf-` / `b-` / `cron-`, EC-5).\n *\n * @public\n */\nexport class InvalidTaskIdError extends TheokitAgentError {\n override readonly name: string = \"InvalidTaskIdError\";\n readonly taskId: string;\n\n constructor(message: string, taskId: string, options: { cause?: unknown } = {}) {\n super(message, {\n ...options,\n isRetryable: false,\n code: \"invalid_task_id\",\n });\n this.taskId = taskId;\n }\n}\n\n/**\n * Thrown when `Task.subscribe(id)` is called for a task that has been\n * evicted, never submitted, or evicted after retention (D373).\n *\n * @public\n */\nexport class TaskNotFoundError extends TheokitAgentError {\n override readonly name: string = \"TaskNotFoundError\";\n readonly taskId: string;\n\n constructor(taskId: string, options: { cause?: unknown } = {}) {\n super(`Task not found: ${taskId}`, {\n ...options,\n isRetryable: false,\n code: \"task_not_found\",\n });\n this.taskId = taskId;\n }\n}\n\n/**\n * Thrown when `CloudAgent` is asked to wrap a task (D370). Cloud\n * task observability is deferred until Theo PaaS GA.\n *\n * @public\n */\nexport class UnsupportedTaskOperationError extends TheokitAgentError {\n override readonly name: string = \"UnsupportedTaskOperationError\";\n readonly operation: string;\n\n constructor(operation: string, options: { cause?: unknown } = {}) {\n super(\n `Task operation \"${operation}\" is not supported on CloudAgent (pre-release; see ADR D370)`,\n {\n ...options,\n isRetryable: false,\n code: \"task_op_unsupported\",\n },\n );\n this.operation = operation;\n }\n}\n\n/**\n * Thrown by `Budget` enforcement (ADR D386) when a `mode: \"block\"`\n * budget would be exceeded by the upcoming LLM call. Caller pega\n * tipado para retry-after-window-reset or surface to the user.\n *\n * @public\n */\nexport class BudgetExceededError extends TheokitAgentError {\n override readonly name: string = \"BudgetExceededError\";\n readonly budgetName: string;\n readonly window: import(\"./types/budget.js\").BudgetWindow;\n readonly spentUsd: number;\n readonly limitUsd: number;\n readonly mode: import(\"./types/budget.js\").BudgetMode;\n\n constructor(args: {\n budgetName: string;\n window: import(\"./types/budget.js\").BudgetWindow;\n spentUsd: number;\n limitUsd: number;\n mode: import(\"./types/budget.js\").BudgetMode;\n cause?: unknown;\n }) {\n super(\n `Budget \"${args.budgetName}\" exceeded for window ${args.window}: spent $${args.spentUsd.toFixed(4)} > limit $${args.limitUsd.toFixed(4)}`,\n {\n ...(args.cause !== undefined ? { cause: args.cause } : {}),\n isRetryable: false,\n code: \"budget_exceeded\",\n },\n );\n this.budgetName = args.budgetName;\n this.window = args.window;\n this.spentUsd = args.spentUsd;\n this.limitUsd = args.limitUsd;\n this.mode = args.mode;\n }\n}\n\n/**\n * Thrown when `CloudAgent.send({ budget })` is invoked (D388). Cloud\n * budget surface waits for Theo PaaS GA.\n *\n * @public\n */\n/**\n * T1.6 — Thrown when a consumer calls `agent.send()` or any method\n * on an agent that has already been `dispose()`d. Pre-T1.6 this was\n * a generic `new Error(\"Agent has been disposed\")` — consumers\n * couldn't catch it without string-matching the message.\n *\n * @public\n */\nexport class AgentDisposedError extends TheokitAgentError {\n override readonly name: string = \"AgentDisposedError\";\n readonly agentId: string;\n\n constructor(agentId: string) {\n super(`Agent \"${agentId}\" has been disposed. Create a new agent or use Agent.resume().`, {\n isRetryable: false,\n code: \"agent_disposed\",\n });\n this.agentId = agentId;\n }\n}\n\nexport class UnsupportedBudgetOperationError extends TheokitAgentError {\n override readonly name: string = \"UnsupportedBudgetOperationError\";\n readonly operation: string;\n\n constructor(operation: string, options: { cause?: unknown } = {}) {\n super(\n `Budget operation \"${operation}\" is not supported on CloudAgent (pre-release; see ADR D388)`,\n {\n ...options,\n isRetryable: false,\n code: \"budget_op_unsupported\",\n },\n );\n this.operation = operation;\n }\n}\n","/**\n * Async-aware counting semaphore (ADR D135).\n *\n * N-permit gate for cooperative concurrency control inside a single\n * Node process. Used by `Agent.batch` to bound parallel agent count\n * without pulling in `p-limit` or `p-queue` (~30 LoC in-house).\n *\n * Contract: `acquire()` returns a release function. Caller MUST call\n * release exactly once when done — typically in a `finally` block.\n * Release is idempotent (multiple calls are no-ops after the first)\n * for defense against caller bugs, but leaking the release function\n * permanently consumes one permit (EC-G — caller responsibility).\n *\n * @internal\n */\n\nimport { ConfigurationError } from \"../../../errors.js\";\n\nexport interface AsyncSemaphore {\n /** Acquire a permit. Returns the release function (call once). */\n acquire(): Promise<() => void>;\n /** Permits currently held in flight. */\n inFlight(): number;\n /** Total: in-flight + queued waiters. */\n pending(): number;\n}\n\nexport function createSemaphore(permits: number): AsyncSemaphore {\n if (!Number.isInteger(permits) || permits < 1) {\n throw new ConfigurationError(\n `async-semaphore: permits must be a positive integer, got ${permits}`,\n { code: \"invalid_concurrency\" },\n );\n }\n let active = 0;\n const queue: Array<() => void> = [];\n\n function tryGrant(): void {\n if (active < permits && queue.length > 0) {\n const resolve = queue.shift();\n if (resolve !== undefined) {\n active += 1;\n resolve();\n }\n }\n }\n\n return {\n inFlight: () => active,\n pending: () => queue.length + active,\n async acquire() {\n await new Promise<void>((resolve) => {\n queue.push(resolve);\n tryGrant();\n });\n let released = false;\n return () => {\n if (released) return;\n released = true;\n active -= 1;\n tryGrant();\n };\n },\n };\n}\n","/**\n * Ordered, bounded-concurrency parallel map (plan m0-foundation-expose-primitives, M0-2).\n *\n * Runs `fn` over `items` with at most `concurrency` invocations in flight at\n * once, preserving input order in the result array. Fail-fast: rejects with the\n * first error a task throws (matching the in-house `boundedParallel`/`runBatches`\n * clones this consolidates). Backed by the in-house {@link createSemaphore}\n * (ADR D135 — no `p-limit`/`p-map` dependency).\n *\n * @internal — public via `@theokit/sdk/concurrency`\n */\n\nimport { createSemaphore } from \"./async-semaphore.js\";\n\nconst NEVER_ABORT: AbortSignal = new AbortController().signal;\n\n/**\n * Map `fn` over `items` with bounded concurrency, preserving order.\n *\n * @param items - inputs to process\n * @param concurrency - max in-flight invocations (positive integer; validated)\n * @param fn - async mapper; receives the item, its index, and an abort signal\n * @param options.signal - optional abort signal; once aborted, no new `fn`\n * invocation is started (in-flight ones are not force-cancelled)\n * @returns results in the same order as `items`\n * @throws ConfigurationError when `concurrency` is not a positive integer\n *\n * @example\n * await mapWithConcurrency([1, 2, 3], 2, async (n) => n * 2); // [2, 4, 6]\n */\nexport async function mapWithConcurrency<T, R>(\n items: ReadonlyArray<T>,\n concurrency: number,\n fn: (item: T, index: number, signal: AbortSignal) => Promise<R>,\n options?: { signal?: AbortSignal },\n): Promise<R[]> {\n const semaphore = createSemaphore(concurrency);\n const signal = options?.signal ?? NEVER_ABORT;\n return Promise.all(\n items.map(async (item, index) => {\n const release = await semaphore.acquire();\n try {\n if (signal.aborted) {\n throw signal.reason instanceof Error\n ? signal.reason\n : new Error(\"mapWithConcurrency: aborted\");\n }\n return await fn(item, index, signal);\n } finally {\n release();\n }\n }),\n );\n}\n","/**\n * Public concurrency primitives (plan m0-foundation-expose-primitives, M0-2).\n *\n * Thin re-export of the in-house concurrency helpers (ADR D135 — no\n * `p-limit`/`p-map` dependency). Split into its own top-level module so\n * `tsup` builds a dedicated `@theokit/sdk/concurrency` sub-path entry,\n * mirroring the `path-safety` pattern.\n *\n * - `createSemaphore(permits)` — N-permit async-aware counting semaphore.\n * - `mapWithConcurrency(items, concurrency, fn, opts?)` — ordered bounded map.\n */\n\nimport {\n type AsyncSemaphore,\n createSemaphore,\n} from \"./internal/runtime/concurrency/async-semaphore.js\";\n\nexport type { AsyncSemaphore };\n\n/** SE36 — `Semaphore.create` replaces `createSemaphore` (ADR 0015). @public */\nexport class Semaphore {\n private constructor() {}\n static create(permits: number): AsyncSemaphore {\n return createSemaphore(permits);\n }\n}\nexport { mapWithConcurrency } from \"./internal/runtime/concurrency/map-with-concurrency.js\";\n"]}
|
package/dist/concurrency.d.cts
CHANGED
|
@@ -9,5 +9,11 @@
|
|
|
9
9
|
* - `createSemaphore(permits)` — N-permit async-aware counting semaphore.
|
|
10
10
|
* - `mapWithConcurrency(items, concurrency, fn, opts?)` — ordered bounded map.
|
|
11
11
|
*/
|
|
12
|
-
|
|
12
|
+
import { type AsyncSemaphore } from "./internal/runtime/concurrency/async-semaphore.js";
|
|
13
|
+
export type { AsyncSemaphore };
|
|
14
|
+
/** SE36 — `Semaphore.create` replaces `createSemaphore` (ADR 0015). @public */
|
|
15
|
+
export declare class Semaphore {
|
|
16
|
+
private constructor();
|
|
17
|
+
static create(permits: number): AsyncSemaphore;
|
|
18
|
+
}
|
|
13
19
|
export { mapWithConcurrency } from "./internal/runtime/concurrency/map-with-concurrency.js";
|
package/dist/concurrency.d.ts
CHANGED
|
@@ -9,5 +9,11 @@
|
|
|
9
9
|
* - `createSemaphore(permits)` — N-permit async-aware counting semaphore.
|
|
10
10
|
* - `mapWithConcurrency(items, concurrency, fn, opts?)` — ordered bounded map.
|
|
11
11
|
*/
|
|
12
|
-
|
|
12
|
+
import { type AsyncSemaphore } from "./internal/runtime/concurrency/async-semaphore.js";
|
|
13
|
+
export type { AsyncSemaphore };
|
|
14
|
+
/** SE36 — `Semaphore.create` replaces `createSemaphore` (ADR 0015). @public */
|
|
15
|
+
export declare class Semaphore {
|
|
16
|
+
private constructor();
|
|
17
|
+
static create(permits: number): AsyncSemaphore;
|
|
18
|
+
}
|
|
13
19
|
export { mapWithConcurrency } from "./internal/runtime/concurrency/map-with-concurrency.js";
|
package/dist/concurrency.js
CHANGED
|
@@ -78,6 +78,15 @@ async function mapWithConcurrency(items, concurrency, fn, options) {
|
|
|
78
78
|
);
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
|
|
81
|
+
// src/concurrency.ts
|
|
82
|
+
var Semaphore = class {
|
|
83
|
+
constructor() {
|
|
84
|
+
}
|
|
85
|
+
static create(permits) {
|
|
86
|
+
return createSemaphore(permits);
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
export { Semaphore, mapWithConcurrency };
|
|
82
91
|
//# sourceMappingURL=concurrency.js.map
|
|
83
92
|
//# sourceMappingURL=concurrency.js.map
|
package/dist/concurrency.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors.ts","../src/internal/runtime/concurrency/async-semaphore.ts","../src/internal/runtime/concurrency/map-with-concurrency.ts"],"names":[],"mappings":"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","file":"concurrency.js","sourcesContent":["import { defaultRetriableForCode } from \"./internal/default-retriable.js\";\nimport { redactSecrets } from \"./internal/security/redact.js\";\nimport type { RunOperation } from \"./types/run.js\";\n\n/**\n * Finite, machine-readable error codes for provider-originated errors\n * (ADR D66). Consumers can `switch (err.metadata?.code)` exhaustively\n * — adding a new variant is an explicit decision + test coverage.\n *\n * @public\n */\nexport type ErrorCode =\n | \"rate_limit\"\n | \"auth_failed\"\n | \"invalid_request\"\n | \"timeout\"\n | \"server_error\"\n | \"context_too_long\"\n | \"content_filtered\"\n | \"model_unavailable\"\n | \"network\"\n | \"quota_exceeded\"\n | \"unknown\";\n\n/**\n * Codes used by {@link AgentRunError} (Production-Readiness #3, ADR D311).\n *\n * Superset of {@link ErrorCode} extended with codes that do NOT originate\n * from a provider HTTP response:\n *\n * - `quota_exceeded` — billing limit hit (provider 402 or signalled error)\n * - `tool_runtime_error` — custom tool handler threw inside dispatch\n * - `aborted` — caller's `AbortSignal` fired (Phase 4)\n * - `invalid_model` — model id rejected by provider (400 \"model not found\")\n * - `safety_blocked` — provider safety filter blocked req or resp\n * - `provider_unreachable` — DNS/TCP/timeout/5xx at transport boundary\n *\n * The `& {}` tail keeps the literal-union ergonomics (autocomplete) while\n * accepting any string for forward compatibility with constructor calls\n * that pass arbitrary code values (legacy callers).\n *\n * @public\n */\n/**\n * T1.1 — closed literal union for `AgentRunError.code`. The previous\n * `(string & {})` escape hatch let arbitrary strings slip into the type\n * surface and defeated exhaustive `switch (code)` discrimination. This is\n * the canonical closed form. `AgentRunErrorCode` is re-aliased below for\n * source-level back-compat.\n *\n * Adding a new code: append the literal here AND audit every `switch (err.code)`\n * in callers. Type-checker enforces the audit via the `default: assertNever(code)`\n * convention.\n *\n * @public\n */\nexport type KnownAgentRunErrorCode =\n | ErrorCode\n | \"quota_exceeded\"\n | \"tool_runtime_error\"\n | \"aborted\"\n | \"invalid_model\"\n | \"safety_blocked\"\n | \"provider_unreachable\";\n\n/**\n * Back-compat alias of {@link KnownAgentRunErrorCode}. Pre-T1.1 callers that\n * imported `AgentRunErrorCode` keep working; new code SHOULD prefer\n * `KnownAgentRunErrorCode` to make the closed-union intent explicit.\n *\n * @public\n */\nexport type AgentRunErrorCode = KnownAgentRunErrorCode;\n\n/** Snapshot of every known code at runtime — used by the boundary coercer. */\nconst KNOWN_AGENT_RUN_ERROR_CODES = new Set<string>([\n \"rate_limit\",\n \"auth_failed\",\n \"invalid_request\",\n \"timeout\",\n \"server_error\",\n \"context_too_long\",\n \"content_filtered\",\n \"model_unavailable\",\n \"network\",\n \"unknown\",\n \"quota_exceeded\",\n \"tool_runtime_error\",\n \"aborted\",\n \"invalid_model\",\n \"safety_blocked\",\n \"provider_unreachable\",\n]);\n\n/**\n * T1.1 boundary helper — coerce an arbitrary string (typically arriving from\n * a downstream `RunErrorDetail.code` or a deserialized cloud response) into a\n * `KnownAgentRunErrorCode`. Unknown strings collapse to `\"unknown\"` so the\n * closed type contract holds without forcing every caller to switch.\n *\n * @internal\n */\nexport function coerceToKnownAgentRunErrorCode(code: string | undefined): KnownAgentRunErrorCode {\n if (code !== undefined && KNOWN_AGENT_RUN_ERROR_CODES.has(code)) {\n return code as KnownAgentRunErrorCode;\n }\n return \"unknown\";\n}\n\n/**\n * Structured context for errors that originated from a provider HTTP\n * call (ADR D65). Lets callers retry with the right backoff (`retryAfter`),\n * surface actionable diagnostics (`provider`, `endpoint`), and inspect the\n * raw response body when needed (`raw`, capped at ~2KB by the mapper).\n *\n * @public\n */\nexport interface ErrorMetadata {\n /** Provider canonical name (e.g., `\"anthropic\"`, `\"openai\"`, `\"openrouter\"`, `\"gemini\"`). */\n provider: string;\n /** HTTP endpoint that failed (e.g., `\"/v1/messages\"`, `\"/v1/chat/completions\"`). */\n endpoint: string;\n /** Machine-readable error code (finite enum). */\n code: ErrorCode;\n /** HTTP status code if applicable. */\n statusCode?: number;\n /** Seconds to wait before retry, per provider's `retry-after` header (numeric form only). */\n retryAfter?: number;\n /** Raw response body for debugging (truncated to ~2KB by the mapper). */\n raw?: unknown;\n}\n\n/**\n * Base class for all errors thrown by `@theokit/sdk`.\n *\n * Use `isRetryable` to drive retry/backoff logic. `code` and `protoErrorCode`\n * are populated for server-originated errors when available. `metadata`\n * (ADR D65) carries structured `{ provider, endpoint, code, ... }` when\n * the error originated from a provider HTTP call.\n *\n * @public\n */\nexport class TheokitAgentError extends Error {\n override readonly name: string = \"TheokitAgentError\";\n readonly isRetryable: boolean;\n readonly code?: string;\n readonly protoErrorCode?: string;\n readonly metadata?: ErrorMetadata;\n\n constructor(\n message: string,\n options: {\n isRetryable?: boolean;\n code?: string;\n protoErrorCode?: string;\n cause?: unknown;\n metadata?: ErrorMetadata;\n } = {},\n ) {\n super(message, options.cause !== undefined ? { cause: options.cause } : undefined);\n this.isRetryable = options.isRetryable ?? false;\n if (options.code !== undefined) this.code = options.code;\n if (options.protoErrorCode !== undefined) this.protoErrorCode = options.protoErrorCode;\n if (options.metadata !== undefined) this.metadata = options.metadata;\n }\n}\n\n/**\n * Invalid API key, not logged in, insufficient permissions.\n *\n * @public\n */\nexport class AuthenticationError extends TheokitAgentError {\n override readonly name: string = \"AuthenticationError\";\n\n constructor(\n message: string,\n options: { code?: string; cause?: unknown; metadata?: ErrorMetadata } = {},\n ) {\n super(message, { ...options, isRetryable: false });\n }\n}\n\n/**\n * Too many requests or usage limits exceeded.\n *\n * @public\n */\nexport class RateLimitError extends TheokitAgentError {\n override readonly name: string = \"RateLimitError\";\n\n constructor(\n message: string,\n options: { code?: string; cause?: unknown; metadata?: ErrorMetadata } = {},\n ) {\n super(message, { ...options, isRetryable: true });\n }\n}\n\n/**\n * Invalid model, bad request parameters, malformed options.\n *\n * @public\n */\nexport class ConfigurationError extends TheokitAgentError {\n override readonly name: string = \"ConfigurationError\";\n\n constructor(\n message: string,\n options: { code?: string; cause?: unknown; metadata?: ErrorMetadata } = {},\n ) {\n super(message, { ...options, isRetryable: false });\n }\n}\n\n/**\n * Thrown when creating a cloud agent for a repo whose SCM provider is not\n * connected. Use `helpUrl` to point the user at the right reconnect flow.\n *\n * @public\n */\nexport class IntegrationNotConnectedError extends ConfigurationError {\n override readonly name: string = \"IntegrationNotConnectedError\";\n readonly provider: string;\n readonly helpUrl: string;\n\n constructor(\n message: string,\n options: {\n provider: string;\n helpUrl: string;\n code?: string;\n cause?: unknown;\n metadata?: ErrorMetadata;\n },\n ) {\n super(message, options);\n this.provider = options.provider;\n this.helpUrl = options.helpUrl;\n }\n}\n\n/**\n * Service unavailable, timeout, transport-level failure.\n *\n * @public\n */\nexport class NetworkError extends TheokitAgentError {\n override readonly name: string = \"NetworkError\";\n\n constructor(\n message: string,\n options: { code?: string; cause?: unknown; metadata?: ErrorMetadata } = {},\n ) {\n super(message, { ...options, isRetryable: true });\n }\n}\n\n/**\n * Catch-all for unclassified server or runtime errors.\n *\n * @public\n */\nexport class UnknownAgentError extends TheokitAgentError {\n override readonly name: string = \"UnknownAgentError\";\n\n constructor(\n message: string,\n options: { code?: string; cause?: unknown; metadata?: ErrorMetadata } = {},\n ) {\n super(message, { ...options, isRetryable: false });\n }\n}\n\n/**\n * Thrown by `Agent.prompt` (and helpers that go through `run.wait()`) when\n * the option `{ throwOnError: true }` is set and the run terminates with\n * `status: 'error'`. Carries the structured `RunResult.error` fields so\n * callers can `catch` once and branch on `code` / `provider` instead of\n * unwrapping the run.\n *\n * Extends {@link TheokitAgentError} per ADR D65 — no new hierarchy.\n *\n * @example\n * try {\n * await Agent.prompt(msg, { apiKey, model, throwOnError: true });\n * } catch (err) {\n * if (err instanceof AgentRunError && err.code === 'auth_failed') {\n * // bad key\n * }\n * }\n *\n * @public\n */\nexport class AgentRunError extends TheokitAgentError {\n override readonly name: string = \"AgentRunError\";\n readonly provider?: string;\n readonly raw?: string;\n /** Provider's request id (`x-request-id` / `request-id` header). Useful for support tickets. */\n readonly requestId?: string;\n /** SDK conversation id this error was raised inside. */\n readonly conversationId?: string;\n\n constructor(\n message: string,\n options: {\n code: AgentRunErrorCode;\n provider?: string;\n raw?: string;\n requestId?: string;\n conversationId?: string;\n retriable?: boolean;\n cause?: unknown;\n metadata?: ErrorMetadata;\n },\n ) {\n super(message, {\n code: options.code,\n cause: options.cause,\n metadata: options.metadata,\n // D311: most AgentRunErrors are not retriable (auth, validation, abort).\n // Provider mappers (D314) override per-status — explicit `retriable` wins\n // over the implicit default when supplied.\n isRetryable: options.retriable ?? defaultRetriableForCode(options.code),\n });\n if (options.provider !== undefined) this.provider = options.provider;\n if (options.raw !== undefined) this.raw = options.raw;\n if (options.requestId !== undefined) this.requestId = options.requestId;\n if (options.conversationId !== undefined) this.conversationId = options.conversationId;\n }\n\n /**\n * Production-Readiness #3 (ADR D311): alias for `isRetryable` exposed as\n * `retriable` to match the handoff contract. Future v2 will deprecate\n * `isRetryable` in favor of this.\n */\n get retriable(): boolean {\n return this.isRetryable;\n }\n\n /**\n * D312: provider's `Retry-After` header in **milliseconds**. Mappers store\n * the header value (seconds) in `metadata.retryAfter`; this getter\n * multiplies by 1000 so the result composes with `Date.now()`/`setTimeout`.\n *\n * Returns `undefined` when no hint was provided. `0` is a legitimate value\n * — use `=== undefined` check rather than truthy check.\n */\n get retryAfterMs(): number | undefined {\n if (this.metadata?.retryAfter === undefined) return undefined;\n return this.metadata.retryAfter * 1000;\n }\n\n /**\n * D313 + T1.5: alias for `metadata.raw`. Provider response body for\n * debugging. T1.5 wraps the value in `redactSecrets` at the getter\n * boundary so secret-shaped substrings (`sk-...`, Bearer JWTs, etc.) are\n * stripped before reaching the caller. Available but NEVER serialized\n * into `.message` (anti-leak invariant).\n */\n get providerError(): unknown {\n const raw = this.metadata?.raw;\n if (raw === undefined) return undefined;\n if (typeof raw === \"string\") return redactSecrets(raw);\n // Non-string raw (object/buffer) — stringify then redact.\n try {\n return redactSecrets(JSON.stringify(raw));\n } catch {\n return redactSecrets(String(raw));\n }\n }\n\n /**\n * T1.5 — sanitized JSON form. `metadata.raw` is OMITTED by default; opt\n * in via `THEOKIT_DEBUG_RAW_ERRORS=1` to surface the (redacted) raw\n * payload for diagnostics. Every other field stays accessible.\n *\n * The single env-var gate is read each call so operators can toggle at\n * runtime without restarting the process.\n */\n toJSON(): Record<string, unknown> {\n const json: Record<string, unknown> = {\n name: this.name,\n message: this.message,\n isRetryable: this.isRetryable,\n };\n addOptionalFields(json, this);\n const safeMeta = sanitizeMetadata(this.metadata);\n if (safeMeta !== undefined) json.metadata = safeMeta;\n return json;\n }\n}\n\nfunction addOptionalFields(json: Record<string, unknown>, err: AgentRunError): void {\n if (err.code !== undefined) json.code = err.code;\n if (err.provider !== undefined) json.provider = err.provider;\n if (err.requestId !== undefined) json.requestId = err.requestId;\n if (err.conversationId !== undefined) json.conversationId = err.conversationId;\n if (err.raw !== undefined) json.raw = redactSecrets(err.raw);\n}\n\nfunction sanitizeMetadata(meta: ErrorMetadata | undefined): ErrorMetadata | undefined {\n if (meta === undefined) return undefined;\n const { raw, ...rest } = meta;\n const debugRaw = process.env.THEOKIT_DEBUG_RAW_ERRORS === \"1\";\n if (debugRaw && raw !== undefined) {\n const redactedRaw =\n typeof raw === \"string\" ? redactSecrets(raw) : redactSecrets(safeStringify(raw));\n return { ...rest, raw: redactedRaw } as ErrorMetadata;\n }\n return rest as ErrorMetadata;\n}\n\nfunction safeStringify(value: unknown): string {\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n}\n\n/**\n * Is this error transient (worth retrying)?\n *\n * Returns the SDK's own retryability verdict: every {@link TheokitAgentError}\n * subclass computes `isRetryable` at construction (rate-limit / network /\n * credential-pool-exhausted are retryable; auth / configuration / unsupported\n * are not), so this predicate is a single source of truth rather than a\n * re-derivation. Non-SDK errors return `false` conservatively — wrap a foreign\n * error in the appropriate SDK error first if you want it considered transient.\n * It never inspects `err.message`.\n *\n * @example\n * try {\n * await agent.send(message, { throwOnError: true });\n * } catch (err) {\n * if (isTransientError(err)) return retryWithBackoff();\n * throw err;\n * }\n *\n * @public\n */\nexport function isTransientError(err: unknown): boolean {\n return err instanceof TheokitAgentError && err.isRetryable === true;\n}\n\n/**\n * Thrown when a {@link Run} or agent operation is not available on the current\n * runtime. Check first with `run.supports(operation)`.\n *\n * Extends {@link TheokitAgentError} (so error-catching code that branches on\n * `instanceof TheokitAgentError` continues to work) but is never retryable —\n * an unsupported operation will not become supported on retry.\n *\n * @public\n */\nexport class UnsupportedRunOperationError extends TheokitAgentError {\n override readonly name: string = \"UnsupportedRunOperationError\";\n readonly operation: RunOperation;\n\n constructor(\n message: string,\n operation: RunOperation,\n options: { code?: string; cause?: unknown } = {},\n ) {\n super(message, {\n ...options,\n isRetryable: false,\n code: options.code ?? \"unsupported_run_operation\",\n });\n this.operation = operation;\n }\n}\n\n/**\n * Thrown when every credential in a per-provider pool is in cooldown\n * and no healthy key is available (ADR D133). The caller's\n * {@link import(\"./internal/llm/fallback-client.js\").FallbackLlmClient}\n * catches this and tries the next provider in the fallback chain.\n *\n * `metadata.nextRetryAt` (epoch ms) tells callers when the soonest\n * pool entry resumes — useful for manual retry scheduling.\n *\n * @public\n */\nexport class CredentialPoolExhaustedError extends TheokitAgentError {\n override readonly name: string = \"CredentialPoolExhaustedError\";\n readonly provider: string;\n readonly nextRetryAt: number | undefined;\n\n constructor(\n message: string,\n options: {\n provider: string;\n nextRetryAt?: number;\n code?: string;\n cause?: unknown;\n metadata?: ErrorMetadata;\n },\n ) {\n super(message, {\n ...options,\n isRetryable: true,\n code: options.code ?? \"credential_pool_exhausted\",\n });\n this.provider = options.provider;\n this.nextRetryAt = options.nextRetryAt;\n }\n}\n\n/**\n * Finite error codes specific to memory adapter operations (ADR D141).\n *\n * @public\n */\nexport type MemoryAdapterErrorCode =\n | \"auth_failed\"\n | \"rate_limited\"\n | \"not_found\"\n | \"network\"\n | \"invalid_input\"\n | \"unknown\";\n\n/**\n * Error raised by `@theokit-memory-*` adapters. Carries `adapterId`\n * so callers can branch on which provider failed (ADR D141).\n *\n * @public\n */\nexport class MemoryAdapterError extends TheokitAgentError {\n override readonly name: string = \"MemoryAdapterError\";\n readonly adapterId: string;\n\n constructor(\n message: string,\n options: {\n adapterId: string;\n code: MemoryAdapterErrorCode;\n cause?: unknown;\n metadata?: ErrorMetadata;\n },\n ) {\n super(message, {\n isRetryable: options.code === \"rate_limited\" || options.code === \"network\",\n code: options.code,\n ...(options.cause !== undefined ? { cause: options.cause } : {}),\n ...(options.metadata !== undefined ? { metadata: options.metadata } : {}),\n });\n this.adapterId = options.adapterId;\n }\n}\n\n/**\n * Thrown when a user-supplied task ID violates the grammar\n * `^[a-z0-9][a-z0-9_-]*$` (D368) OR starts with a reserved adapter\n * prefix (`wf-` / `b-` / `cron-`, EC-5).\n *\n * @public\n */\nexport class InvalidTaskIdError extends TheokitAgentError {\n override readonly name: string = \"InvalidTaskIdError\";\n readonly taskId: string;\n\n constructor(message: string, taskId: string, options: { cause?: unknown } = {}) {\n super(message, {\n ...options,\n isRetryable: false,\n code: \"invalid_task_id\",\n });\n this.taskId = taskId;\n }\n}\n\n/**\n * Thrown when `Task.subscribe(id)` is called for a task that has been\n * evicted, never submitted, or evicted after retention (D373).\n *\n * @public\n */\nexport class TaskNotFoundError extends TheokitAgentError {\n override readonly name: string = \"TaskNotFoundError\";\n readonly taskId: string;\n\n constructor(taskId: string, options: { cause?: unknown } = {}) {\n super(`Task not found: ${taskId}`, {\n ...options,\n isRetryable: false,\n code: \"task_not_found\",\n });\n this.taskId = taskId;\n }\n}\n\n/**\n * Thrown when `CloudAgent` is asked to wrap a task (D370). Cloud\n * task observability is deferred until Theo PaaS GA.\n *\n * @public\n */\nexport class UnsupportedTaskOperationError extends TheokitAgentError {\n override readonly name: string = \"UnsupportedTaskOperationError\";\n readonly operation: string;\n\n constructor(operation: string, options: { cause?: unknown } = {}) {\n super(\n `Task operation \"${operation}\" is not supported on CloudAgent (pre-release; see ADR D370)`,\n {\n ...options,\n isRetryable: false,\n code: \"task_op_unsupported\",\n },\n );\n this.operation = operation;\n }\n}\n\n/**\n * Thrown by `Budget` enforcement (ADR D386) when a `mode: \"block\"`\n * budget would be exceeded by the upcoming LLM call. Caller pega\n * tipado para retry-after-window-reset or surface to the user.\n *\n * @public\n */\nexport class BudgetExceededError extends TheokitAgentError {\n override readonly name: string = \"BudgetExceededError\";\n readonly budgetName: string;\n readonly window: import(\"./types/budget.js\").BudgetWindow;\n readonly spentUsd: number;\n readonly limitUsd: number;\n readonly mode: import(\"./types/budget.js\").BudgetMode;\n\n constructor(args: {\n budgetName: string;\n window: import(\"./types/budget.js\").BudgetWindow;\n spentUsd: number;\n limitUsd: number;\n mode: import(\"./types/budget.js\").BudgetMode;\n cause?: unknown;\n }) {\n super(\n `Budget \"${args.budgetName}\" exceeded for window ${args.window}: spent $${args.spentUsd.toFixed(4)} > limit $${args.limitUsd.toFixed(4)}`,\n {\n ...(args.cause !== undefined ? { cause: args.cause } : {}),\n isRetryable: false,\n code: \"budget_exceeded\",\n },\n );\n this.budgetName = args.budgetName;\n this.window = args.window;\n this.spentUsd = args.spentUsd;\n this.limitUsd = args.limitUsd;\n this.mode = args.mode;\n }\n}\n\n/**\n * Thrown when `CloudAgent.send({ budget })` is invoked (D388). Cloud\n * budget surface waits for Theo PaaS GA.\n *\n * @public\n */\n/**\n * T1.6 — Thrown when a consumer calls `agent.send()` or any method\n * on an agent that has already been `dispose()`d. Pre-T1.6 this was\n * a generic `new Error(\"Agent has been disposed\")` — consumers\n * couldn't catch it without string-matching the message.\n *\n * @public\n */\nexport class AgentDisposedError extends TheokitAgentError {\n override readonly name: string = \"AgentDisposedError\";\n readonly agentId: string;\n\n constructor(agentId: string) {\n super(`Agent \"${agentId}\" has been disposed. Create a new agent or use Agent.resume().`, {\n isRetryable: false,\n code: \"agent_disposed\",\n });\n this.agentId = agentId;\n }\n}\n\nexport class UnsupportedBudgetOperationError extends TheokitAgentError {\n override readonly name: string = \"UnsupportedBudgetOperationError\";\n readonly operation: string;\n\n constructor(operation: string, options: { cause?: unknown } = {}) {\n super(\n `Budget operation \"${operation}\" is not supported on CloudAgent (pre-release; see ADR D388)`,\n {\n ...options,\n isRetryable: false,\n code: \"budget_op_unsupported\",\n },\n );\n this.operation = operation;\n }\n}\n","/**\n * Async-aware counting semaphore (ADR D135).\n *\n * N-permit gate for cooperative concurrency control inside a single\n * Node process. Used by `Agent.batch` to bound parallel agent count\n * without pulling in `p-limit` or `p-queue` (~30 LoC in-house).\n *\n * Contract: `acquire()` returns a release function. Caller MUST call\n * release exactly once when done — typically in a `finally` block.\n * Release is idempotent (multiple calls are no-ops after the first)\n * for defense against caller bugs, but leaking the release function\n * permanently consumes one permit (EC-G — caller responsibility).\n *\n * @internal\n */\n\nimport { ConfigurationError } from \"../../../errors.js\";\n\nexport interface AsyncSemaphore {\n /** Acquire a permit. Returns the release function (call once). */\n acquire(): Promise<() => void>;\n /** Permits currently held in flight. */\n inFlight(): number;\n /** Total: in-flight + queued waiters. */\n pending(): number;\n}\n\nexport function createSemaphore(permits: number): AsyncSemaphore {\n if (!Number.isInteger(permits) || permits < 1) {\n throw new ConfigurationError(\n `async-semaphore: permits must be a positive integer, got ${permits}`,\n { code: \"invalid_concurrency\" },\n );\n }\n let active = 0;\n const queue: Array<() => void> = [];\n\n function tryGrant(): void {\n if (active < permits && queue.length > 0) {\n const resolve = queue.shift();\n if (resolve !== undefined) {\n active += 1;\n resolve();\n }\n }\n }\n\n return {\n inFlight: () => active,\n pending: () => queue.length + active,\n async acquire() {\n await new Promise<void>((resolve) => {\n queue.push(resolve);\n tryGrant();\n });\n let released = false;\n return () => {\n if (released) return;\n released = true;\n active -= 1;\n tryGrant();\n };\n },\n };\n}\n","/**\n * Ordered, bounded-concurrency parallel map (plan m0-foundation-expose-primitives, M0-2).\n *\n * Runs `fn` over `items` with at most `concurrency` invocations in flight at\n * once, preserving input order in the result array. Fail-fast: rejects with the\n * first error a task throws (matching the in-house `boundedParallel`/`runBatches`\n * clones this consolidates). Backed by the in-house {@link createSemaphore}\n * (ADR D135 — no `p-limit`/`p-map` dependency).\n *\n * @internal — public via `@theokit/sdk/concurrency`\n */\n\nimport { createSemaphore } from \"./async-semaphore.js\";\n\nconst NEVER_ABORT: AbortSignal = new AbortController().signal;\n\n/**\n * Map `fn` over `items` with bounded concurrency, preserving order.\n *\n * @param items - inputs to process\n * @param concurrency - max in-flight invocations (positive integer; validated)\n * @param fn - async mapper; receives the item, its index, and an abort signal\n * @param options.signal - optional abort signal; once aborted, no new `fn`\n * invocation is started (in-flight ones are not force-cancelled)\n * @returns results in the same order as `items`\n * @throws ConfigurationError when `concurrency` is not a positive integer\n *\n * @example\n * await mapWithConcurrency([1, 2, 3], 2, async (n) => n * 2); // [2, 4, 6]\n */\nexport async function mapWithConcurrency<T, R>(\n items: ReadonlyArray<T>,\n concurrency: number,\n fn: (item: T, index: number, signal: AbortSignal) => Promise<R>,\n options?: { signal?: AbortSignal },\n): Promise<R[]> {\n const semaphore = createSemaphore(concurrency);\n const signal = options?.signal ?? NEVER_ABORT;\n return Promise.all(\n items.map(async (item, index) => {\n const release = await semaphore.acquire();\n try {\n if (signal.aborted) {\n throw signal.reason instanceof Error\n ? signal.reason\n : new Error(\"mapWithConcurrency: aborted\");\n }\n return await fn(item, index, signal);\n } finally {\n release();\n }\n }),\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/internal/runtime/concurrency/async-semaphore.ts","../src/internal/runtime/concurrency/map-with-concurrency.ts","../src/concurrency.ts"],"names":[],"mappings":"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","file":"concurrency.js","sourcesContent":["import { defaultRetriableForCode } from \"./internal/default-retriable.js\";\nimport { redactSecrets } from \"./internal/security/redact.js\";\nimport type { RunOperation } from \"./types/run.js\";\n\n/**\n * Finite, machine-readable error codes for provider-originated errors\n * (ADR D66). Consumers can `switch (err.metadata?.code)` exhaustively\n * — adding a new variant is an explicit decision + test coverage.\n *\n * @public\n */\nexport type ErrorCode =\n | \"rate_limit\"\n | \"auth_failed\"\n | \"invalid_request\"\n | \"timeout\"\n | \"server_error\"\n | \"context_too_long\"\n | \"content_filtered\"\n | \"model_unavailable\"\n | \"network\"\n | \"quota_exceeded\"\n | \"unknown\";\n\n/**\n * Codes used by {@link AgentRunError} (Production-Readiness #3, ADR D311).\n *\n * Superset of {@link ErrorCode} extended with codes that do NOT originate\n * from a provider HTTP response:\n *\n * - `quota_exceeded` — billing limit hit (provider 402 or signalled error)\n * - `tool_runtime_error` — custom tool handler threw inside dispatch\n * - `aborted` — caller's `AbortSignal` fired (Phase 4)\n * - `invalid_model` — model id rejected by provider (400 \"model not found\")\n * - `safety_blocked` — provider safety filter blocked req or resp\n * - `provider_unreachable` — DNS/TCP/timeout/5xx at transport boundary\n *\n * The `& {}` tail keeps the literal-union ergonomics (autocomplete) while\n * accepting any string for forward compatibility with constructor calls\n * that pass arbitrary code values (legacy callers).\n *\n * @public\n */\n/**\n * T1.1 — closed literal union for `AgentRunError.code`. The previous\n * `(string & {})` escape hatch let arbitrary strings slip into the type\n * surface and defeated exhaustive `switch (code)` discrimination. This is\n * the canonical closed form. `AgentRunErrorCode` is re-aliased below for\n * source-level back-compat.\n *\n * Adding a new code: append the literal here AND audit every `switch (err.code)`\n * in callers. Type-checker enforces the audit via the `default: assertNever(code)`\n * convention.\n *\n * @public\n */\nexport type KnownAgentRunErrorCode =\n | ErrorCode\n | \"quota_exceeded\"\n | \"tool_runtime_error\"\n | \"aborted\"\n | \"invalid_model\"\n | \"safety_blocked\"\n | \"provider_unreachable\";\n\n/**\n * Back-compat alias of {@link KnownAgentRunErrorCode}. Pre-T1.1 callers that\n * imported `AgentRunErrorCode` keep working; new code SHOULD prefer\n * `KnownAgentRunErrorCode` to make the closed-union intent explicit.\n *\n * @public\n */\nexport type AgentRunErrorCode = KnownAgentRunErrorCode;\n\n/** Snapshot of every known code at runtime — used by the boundary coercer. */\nconst KNOWN_AGENT_RUN_ERROR_CODES = new Set<string>([\n \"rate_limit\",\n \"auth_failed\",\n \"invalid_request\",\n \"timeout\",\n \"server_error\",\n \"context_too_long\",\n \"content_filtered\",\n \"model_unavailable\",\n \"network\",\n \"unknown\",\n \"quota_exceeded\",\n \"tool_runtime_error\",\n \"aborted\",\n \"invalid_model\",\n \"safety_blocked\",\n \"provider_unreachable\",\n]);\n\n/**\n * T1.1 boundary helper — coerce an arbitrary string (typically arriving from\n * a downstream `RunErrorDetail.code` or a deserialized cloud response) into a\n * `KnownAgentRunErrorCode`. Unknown strings collapse to `\"unknown\"` so the\n * closed type contract holds without forcing every caller to switch.\n *\n * @internal\n */\nexport function coerceToKnownAgentRunErrorCode(code: string | undefined): KnownAgentRunErrorCode {\n if (code !== undefined && KNOWN_AGENT_RUN_ERROR_CODES.has(code)) {\n return code as KnownAgentRunErrorCode;\n }\n return \"unknown\";\n}\n\n/**\n * Structured context for errors that originated from a provider HTTP\n * call (ADR D65). Lets callers retry with the right backoff (`retryAfter`),\n * surface actionable diagnostics (`provider`, `endpoint`), and inspect the\n * raw response body when needed (`raw`, capped at ~2KB by the mapper).\n *\n * @public\n */\nexport interface ErrorMetadata {\n /** Provider canonical name (e.g., `\"anthropic\"`, `\"openai\"`, `\"openrouter\"`, `\"gemini\"`). */\n provider: string;\n /** HTTP endpoint that failed (e.g., `\"/v1/messages\"`, `\"/v1/chat/completions\"`). */\n endpoint: string;\n /** Machine-readable error code (finite enum). */\n code: ErrorCode;\n /** HTTP status code if applicable. */\n statusCode?: number;\n /** Seconds to wait before retry, per provider's `retry-after` header (numeric form only). */\n retryAfter?: number;\n /** Raw response body for debugging (truncated to ~2KB by the mapper). */\n raw?: unknown;\n}\n\n/**\n * Base class for all errors thrown by `@theokit/sdk`.\n *\n * Use `isRetryable` to drive retry/backoff logic. `code` and `protoErrorCode`\n * are populated for server-originated errors when available. `metadata`\n * (ADR D65) carries structured `{ provider, endpoint, code, ... }` when\n * the error originated from a provider HTTP call.\n *\n * @public\n */\nexport class TheokitAgentError extends Error {\n override readonly name: string = \"TheokitAgentError\";\n readonly isRetryable: boolean;\n readonly code?: string;\n readonly protoErrorCode?: string;\n readonly metadata?: ErrorMetadata;\n\n constructor(\n message: string,\n options: {\n isRetryable?: boolean;\n code?: string;\n protoErrorCode?: string;\n cause?: unknown;\n metadata?: ErrorMetadata;\n } = {},\n ) {\n super(message, options.cause !== undefined ? { cause: options.cause } : undefined);\n this.isRetryable = options.isRetryable ?? false;\n if (options.code !== undefined) this.code = options.code;\n if (options.protoErrorCode !== undefined) this.protoErrorCode = options.protoErrorCode;\n if (options.metadata !== undefined) this.metadata = options.metadata;\n }\n}\n\n/**\n * Invalid API key, not logged in, insufficient permissions.\n *\n * @public\n */\nexport class AuthenticationError extends TheokitAgentError {\n override readonly name: string = \"AuthenticationError\";\n\n constructor(\n message: string,\n options: { code?: string; cause?: unknown; metadata?: ErrorMetadata } = {},\n ) {\n super(message, { ...options, isRetryable: false });\n }\n}\n\n/**\n * Too many requests or usage limits exceeded.\n *\n * @public\n */\nexport class RateLimitError extends TheokitAgentError {\n override readonly name: string = \"RateLimitError\";\n\n constructor(\n message: string,\n options: { code?: string; cause?: unknown; metadata?: ErrorMetadata } = {},\n ) {\n super(message, { ...options, isRetryable: true });\n }\n}\n\n/**\n * Invalid model, bad request parameters, malformed options.\n *\n * @public\n */\nexport class ConfigurationError extends TheokitAgentError {\n override readonly name: string = \"ConfigurationError\";\n\n constructor(\n message: string,\n options: { code?: string; cause?: unknown; metadata?: ErrorMetadata } = {},\n ) {\n super(message, { ...options, isRetryable: false });\n }\n}\n\n/**\n * Thrown when creating a cloud agent for a repo whose SCM provider is not\n * connected. Use `helpUrl` to point the user at the right reconnect flow.\n *\n * @public\n */\nexport class IntegrationNotConnectedError extends ConfigurationError {\n override readonly name: string = \"IntegrationNotConnectedError\";\n readonly provider: string;\n readonly helpUrl: string;\n\n constructor(\n message: string,\n options: {\n provider: string;\n helpUrl: string;\n code?: string;\n cause?: unknown;\n metadata?: ErrorMetadata;\n },\n ) {\n super(message, options);\n this.provider = options.provider;\n this.helpUrl = options.helpUrl;\n }\n}\n\n/**\n * Service unavailable, timeout, transport-level failure.\n *\n * @public\n */\nexport class NetworkError extends TheokitAgentError {\n override readonly name: string = \"NetworkError\";\n\n constructor(\n message: string,\n options: { code?: string; cause?: unknown; metadata?: ErrorMetadata } = {},\n ) {\n super(message, { ...options, isRetryable: true });\n }\n}\n\n/**\n * Catch-all for unclassified server or runtime errors.\n *\n * @public\n */\nexport class UnknownAgentError extends TheokitAgentError {\n override readonly name: string = \"UnknownAgentError\";\n\n constructor(\n message: string,\n options: { code?: string; cause?: unknown; metadata?: ErrorMetadata } = {},\n ) {\n super(message, { ...options, isRetryable: false });\n }\n}\n\n/**\n * Thrown by `Agent.prompt` (and helpers that go through `run.wait()`) when\n * the option `{ throwOnError: true }` is set and the run terminates with\n * `status: 'error'`. Carries the structured `RunResult.error` fields so\n * callers can `catch` once and branch on `code` / `provider` instead of\n * unwrapping the run.\n *\n * Extends {@link TheokitAgentError} per ADR D65 — no new hierarchy.\n *\n * @example\n * try {\n * await Agent.prompt(msg, { apiKey, model, throwOnError: true });\n * } catch (err) {\n * if (err instanceof AgentRunError && err.code === 'auth_failed') {\n * // bad key\n * }\n * }\n *\n * @public\n */\nexport class AgentRunError extends TheokitAgentError {\n override readonly name: string = \"AgentRunError\";\n readonly provider?: string;\n readonly raw?: string;\n /** Provider's request id (`x-request-id` / `request-id` header). Useful for support tickets. */\n readonly requestId?: string;\n /** SDK conversation id this error was raised inside. */\n readonly conversationId?: string;\n\n constructor(\n message: string,\n options: {\n code: AgentRunErrorCode;\n provider?: string;\n raw?: string;\n requestId?: string;\n conversationId?: string;\n retriable?: boolean;\n cause?: unknown;\n metadata?: ErrorMetadata;\n },\n ) {\n super(message, {\n code: options.code,\n cause: options.cause,\n metadata: options.metadata,\n // D311: most AgentRunErrors are not retriable (auth, validation, abort).\n // Provider mappers (D314) override per-status — explicit `retriable` wins\n // over the implicit default when supplied.\n isRetryable: options.retriable ?? defaultRetriableForCode(options.code),\n });\n if (options.provider !== undefined) this.provider = options.provider;\n if (options.raw !== undefined) this.raw = options.raw;\n if (options.requestId !== undefined) this.requestId = options.requestId;\n if (options.conversationId !== undefined) this.conversationId = options.conversationId;\n }\n\n /**\n * Production-Readiness #3 (ADR D311): alias for `isRetryable` exposed as\n * `retriable` to match the handoff contract. Future v2 will deprecate\n * `isRetryable` in favor of this.\n */\n get retriable(): boolean {\n return this.isRetryable;\n }\n\n /**\n * D312: provider's `Retry-After` header in **milliseconds**. Mappers store\n * the header value (seconds) in `metadata.retryAfter`; this getter\n * multiplies by 1000 so the result composes with `Date.now()`/`setTimeout`.\n *\n * Returns `undefined` when no hint was provided. `0` is a legitimate value\n * — use `=== undefined` check rather than truthy check.\n */\n get retryAfterMs(): number | undefined {\n if (this.metadata?.retryAfter === undefined) return undefined;\n return this.metadata.retryAfter * 1000;\n }\n\n /**\n * D313 + T1.5: alias for `metadata.raw`. Provider response body for\n * debugging. T1.5 wraps the value in `redactSecrets` at the getter\n * boundary so secret-shaped substrings (`sk-...`, Bearer JWTs, etc.) are\n * stripped before reaching the caller. Available but NEVER serialized\n * into `.message` (anti-leak invariant).\n */\n get providerError(): unknown {\n const raw = this.metadata?.raw;\n if (raw === undefined) return undefined;\n if (typeof raw === \"string\") return redactSecrets(raw);\n // Non-string raw (object/buffer) — stringify then redact.\n try {\n return redactSecrets(JSON.stringify(raw));\n } catch {\n return redactSecrets(String(raw));\n }\n }\n\n /**\n * T1.5 — sanitized JSON form. `metadata.raw` is OMITTED by default; opt\n * in via `THEOKIT_DEBUG_RAW_ERRORS=1` to surface the (redacted) raw\n * payload for diagnostics. Every other field stays accessible.\n *\n * The single env-var gate is read each call so operators can toggle at\n * runtime without restarting the process.\n */\n toJSON(): Record<string, unknown> {\n const json: Record<string, unknown> = {\n name: this.name,\n message: this.message,\n isRetryable: this.isRetryable,\n };\n addOptionalFields(json, this);\n const safeMeta = sanitizeMetadata(this.metadata);\n if (safeMeta !== undefined) json.metadata = safeMeta;\n return json;\n }\n}\n\nfunction addOptionalFields(json: Record<string, unknown>, err: AgentRunError): void {\n if (err.code !== undefined) json.code = err.code;\n if (err.provider !== undefined) json.provider = err.provider;\n if (err.requestId !== undefined) json.requestId = err.requestId;\n if (err.conversationId !== undefined) json.conversationId = err.conversationId;\n if (err.raw !== undefined) json.raw = redactSecrets(err.raw);\n}\n\nfunction sanitizeMetadata(meta: ErrorMetadata | undefined): ErrorMetadata | undefined {\n if (meta === undefined) return undefined;\n const { raw, ...rest } = meta;\n const debugRaw = process.env.THEOKIT_DEBUG_RAW_ERRORS === \"1\";\n if (debugRaw && raw !== undefined) {\n const redactedRaw =\n typeof raw === \"string\" ? redactSecrets(raw) : redactSecrets(safeStringify(raw));\n return { ...rest, raw: redactedRaw } as ErrorMetadata;\n }\n return rest as ErrorMetadata;\n}\n\nfunction safeStringify(value: unknown): string {\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n}\n\n/**\n * Is this error transient (worth retrying)?\n *\n * Returns the SDK's own retryability verdict: every {@link TheokitAgentError}\n * subclass computes `isRetryable` at construction (rate-limit / network /\n * credential-pool-exhausted are retryable; auth / configuration / unsupported\n * are not), so this predicate is a single source of truth rather than a\n * re-derivation. Non-SDK errors return `false` conservatively — wrap a foreign\n * error in the appropriate SDK error first if you want it considered transient.\n * It never inspects `err.message`.\n *\n * @example\n * try {\n * await agent.send(message, { throwOnError: true });\n * } catch (err) {\n * if (isTransientError(err)) return retryWithBackoff();\n * throw err;\n * }\n *\n * @public\n */\nexport function isTransientError(err: unknown): boolean {\n return err instanceof TheokitAgentError && err.isRetryable === true;\n}\n\n/**\n * Thrown when a {@link Run} or agent operation is not available on the current\n * runtime. Check first with `run.supports(operation)`.\n *\n * Extends {@link TheokitAgentError} (so error-catching code that branches on\n * `instanceof TheokitAgentError` continues to work) but is never retryable —\n * an unsupported operation will not become supported on retry.\n *\n * @public\n */\nexport class UnsupportedRunOperationError extends TheokitAgentError {\n override readonly name: string = \"UnsupportedRunOperationError\";\n readonly operation: RunOperation;\n\n constructor(\n message: string,\n operation: RunOperation,\n options: { code?: string; cause?: unknown } = {},\n ) {\n super(message, {\n ...options,\n isRetryable: false,\n code: options.code ?? \"unsupported_run_operation\",\n });\n this.operation = operation;\n }\n}\n\n/**\n * Thrown when every credential in a per-provider pool is in cooldown\n * and no healthy key is available (ADR D133). The caller's\n * {@link import(\"./internal/llm/fallback-client.js\").FallbackLlmClient}\n * catches this and tries the next provider in the fallback chain.\n *\n * `metadata.nextRetryAt` (epoch ms) tells callers when the soonest\n * pool entry resumes — useful for manual retry scheduling.\n *\n * @public\n */\nexport class CredentialPoolExhaustedError extends TheokitAgentError {\n override readonly name: string = \"CredentialPoolExhaustedError\";\n readonly provider: string;\n readonly nextRetryAt: number | undefined;\n\n constructor(\n message: string,\n options: {\n provider: string;\n nextRetryAt?: number;\n code?: string;\n cause?: unknown;\n metadata?: ErrorMetadata;\n },\n ) {\n super(message, {\n ...options,\n isRetryable: true,\n code: options.code ?? \"credential_pool_exhausted\",\n });\n this.provider = options.provider;\n this.nextRetryAt = options.nextRetryAt;\n }\n}\n\n/**\n * Finite error codes specific to memory adapter operations (ADR D141).\n *\n * @public\n */\nexport type MemoryAdapterErrorCode =\n | \"auth_failed\"\n | \"rate_limited\"\n | \"not_found\"\n | \"network\"\n | \"invalid_input\"\n | \"unknown\";\n\n/**\n * Error raised by `@theokit-memory-*` adapters. Carries `adapterId`\n * so callers can branch on which provider failed (ADR D141).\n *\n * @public\n */\nexport class MemoryAdapterError extends TheokitAgentError {\n override readonly name: string = \"MemoryAdapterError\";\n readonly adapterId: string;\n\n constructor(\n message: string,\n options: {\n adapterId: string;\n code: MemoryAdapterErrorCode;\n cause?: unknown;\n metadata?: ErrorMetadata;\n },\n ) {\n super(message, {\n isRetryable: options.code === \"rate_limited\" || options.code === \"network\",\n code: options.code,\n ...(options.cause !== undefined ? { cause: options.cause } : {}),\n ...(options.metadata !== undefined ? { metadata: options.metadata } : {}),\n });\n this.adapterId = options.adapterId;\n }\n}\n\n/**\n * Thrown when a user-supplied task ID violates the grammar\n * `^[a-z0-9][a-z0-9_-]*$` (D368) OR starts with a reserved adapter\n * prefix (`wf-` / `b-` / `cron-`, EC-5).\n *\n * @public\n */\nexport class InvalidTaskIdError extends TheokitAgentError {\n override readonly name: string = \"InvalidTaskIdError\";\n readonly taskId: string;\n\n constructor(message: string, taskId: string, options: { cause?: unknown } = {}) {\n super(message, {\n ...options,\n isRetryable: false,\n code: \"invalid_task_id\",\n });\n this.taskId = taskId;\n }\n}\n\n/**\n * Thrown when `Task.subscribe(id)` is called for a task that has been\n * evicted, never submitted, or evicted after retention (D373).\n *\n * @public\n */\nexport class TaskNotFoundError extends TheokitAgentError {\n override readonly name: string = \"TaskNotFoundError\";\n readonly taskId: string;\n\n constructor(taskId: string, options: { cause?: unknown } = {}) {\n super(`Task not found: ${taskId}`, {\n ...options,\n isRetryable: false,\n code: \"task_not_found\",\n });\n this.taskId = taskId;\n }\n}\n\n/**\n * Thrown when `CloudAgent` is asked to wrap a task (D370). Cloud\n * task observability is deferred until Theo PaaS GA.\n *\n * @public\n */\nexport class UnsupportedTaskOperationError extends TheokitAgentError {\n override readonly name: string = \"UnsupportedTaskOperationError\";\n readonly operation: string;\n\n constructor(operation: string, options: { cause?: unknown } = {}) {\n super(\n `Task operation \"${operation}\" is not supported on CloudAgent (pre-release; see ADR D370)`,\n {\n ...options,\n isRetryable: false,\n code: \"task_op_unsupported\",\n },\n );\n this.operation = operation;\n }\n}\n\n/**\n * Thrown by `Budget` enforcement (ADR D386) when a `mode: \"block\"`\n * budget would be exceeded by the upcoming LLM call. Caller pega\n * tipado para retry-after-window-reset or surface to the user.\n *\n * @public\n */\nexport class BudgetExceededError extends TheokitAgentError {\n override readonly name: string = \"BudgetExceededError\";\n readonly budgetName: string;\n readonly window: import(\"./types/budget.js\").BudgetWindow;\n readonly spentUsd: number;\n readonly limitUsd: number;\n readonly mode: import(\"./types/budget.js\").BudgetMode;\n\n constructor(args: {\n budgetName: string;\n window: import(\"./types/budget.js\").BudgetWindow;\n spentUsd: number;\n limitUsd: number;\n mode: import(\"./types/budget.js\").BudgetMode;\n cause?: unknown;\n }) {\n super(\n `Budget \"${args.budgetName}\" exceeded for window ${args.window}: spent $${args.spentUsd.toFixed(4)} > limit $${args.limitUsd.toFixed(4)}`,\n {\n ...(args.cause !== undefined ? { cause: args.cause } : {}),\n isRetryable: false,\n code: \"budget_exceeded\",\n },\n );\n this.budgetName = args.budgetName;\n this.window = args.window;\n this.spentUsd = args.spentUsd;\n this.limitUsd = args.limitUsd;\n this.mode = args.mode;\n }\n}\n\n/**\n * Thrown when `CloudAgent.send({ budget })` is invoked (D388). Cloud\n * budget surface waits for Theo PaaS GA.\n *\n * @public\n */\n/**\n * T1.6 — Thrown when a consumer calls `agent.send()` or any method\n * on an agent that has already been `dispose()`d. Pre-T1.6 this was\n * a generic `new Error(\"Agent has been disposed\")` — consumers\n * couldn't catch it without string-matching the message.\n *\n * @public\n */\nexport class AgentDisposedError extends TheokitAgentError {\n override readonly name: string = \"AgentDisposedError\";\n readonly agentId: string;\n\n constructor(agentId: string) {\n super(`Agent \"${agentId}\" has been disposed. Create a new agent or use Agent.resume().`, {\n isRetryable: false,\n code: \"agent_disposed\",\n });\n this.agentId = agentId;\n }\n}\n\nexport class UnsupportedBudgetOperationError extends TheokitAgentError {\n override readonly name: string = \"UnsupportedBudgetOperationError\";\n readonly operation: string;\n\n constructor(operation: string, options: { cause?: unknown } = {}) {\n super(\n `Budget operation \"${operation}\" is not supported on CloudAgent (pre-release; see ADR D388)`,\n {\n ...options,\n isRetryable: false,\n code: \"budget_op_unsupported\",\n },\n );\n this.operation = operation;\n }\n}\n","/**\n * Async-aware counting semaphore (ADR D135).\n *\n * N-permit gate for cooperative concurrency control inside a single\n * Node process. Used by `Agent.batch` to bound parallel agent count\n * without pulling in `p-limit` or `p-queue` (~30 LoC in-house).\n *\n * Contract: `acquire()` returns a release function. Caller MUST call\n * release exactly once when done — typically in a `finally` block.\n * Release is idempotent (multiple calls are no-ops after the first)\n * for defense against caller bugs, but leaking the release function\n * permanently consumes one permit (EC-G — caller responsibility).\n *\n * @internal\n */\n\nimport { ConfigurationError } from \"../../../errors.js\";\n\nexport interface AsyncSemaphore {\n /** Acquire a permit. Returns the release function (call once). */\n acquire(): Promise<() => void>;\n /** Permits currently held in flight. */\n inFlight(): number;\n /** Total: in-flight + queued waiters. */\n pending(): number;\n}\n\nexport function createSemaphore(permits: number): AsyncSemaphore {\n if (!Number.isInteger(permits) || permits < 1) {\n throw new ConfigurationError(\n `async-semaphore: permits must be a positive integer, got ${permits}`,\n { code: \"invalid_concurrency\" },\n );\n }\n let active = 0;\n const queue: Array<() => void> = [];\n\n function tryGrant(): void {\n if (active < permits && queue.length > 0) {\n const resolve = queue.shift();\n if (resolve !== undefined) {\n active += 1;\n resolve();\n }\n }\n }\n\n return {\n inFlight: () => active,\n pending: () => queue.length + active,\n async acquire() {\n await new Promise<void>((resolve) => {\n queue.push(resolve);\n tryGrant();\n });\n let released = false;\n return () => {\n if (released) return;\n released = true;\n active -= 1;\n tryGrant();\n };\n },\n };\n}\n","/**\n * Ordered, bounded-concurrency parallel map (plan m0-foundation-expose-primitives, M0-2).\n *\n * Runs `fn` over `items` with at most `concurrency` invocations in flight at\n * once, preserving input order in the result array. Fail-fast: rejects with the\n * first error a task throws (matching the in-house `boundedParallel`/`runBatches`\n * clones this consolidates). Backed by the in-house {@link createSemaphore}\n * (ADR D135 — no `p-limit`/`p-map` dependency).\n *\n * @internal — public via `@theokit/sdk/concurrency`\n */\n\nimport { createSemaphore } from \"./async-semaphore.js\";\n\nconst NEVER_ABORT: AbortSignal = new AbortController().signal;\n\n/**\n * Map `fn` over `items` with bounded concurrency, preserving order.\n *\n * @param items - inputs to process\n * @param concurrency - max in-flight invocations (positive integer; validated)\n * @param fn - async mapper; receives the item, its index, and an abort signal\n * @param options.signal - optional abort signal; once aborted, no new `fn`\n * invocation is started (in-flight ones are not force-cancelled)\n * @returns results in the same order as `items`\n * @throws ConfigurationError when `concurrency` is not a positive integer\n *\n * @example\n * await mapWithConcurrency([1, 2, 3], 2, async (n) => n * 2); // [2, 4, 6]\n */\nexport async function mapWithConcurrency<T, R>(\n items: ReadonlyArray<T>,\n concurrency: number,\n fn: (item: T, index: number, signal: AbortSignal) => Promise<R>,\n options?: { signal?: AbortSignal },\n): Promise<R[]> {\n const semaphore = createSemaphore(concurrency);\n const signal = options?.signal ?? NEVER_ABORT;\n return Promise.all(\n items.map(async (item, index) => {\n const release = await semaphore.acquire();\n try {\n if (signal.aborted) {\n throw signal.reason instanceof Error\n ? signal.reason\n : new Error(\"mapWithConcurrency: aborted\");\n }\n return await fn(item, index, signal);\n } finally {\n release();\n }\n }),\n );\n}\n","/**\n * Public concurrency primitives (plan m0-foundation-expose-primitives, M0-2).\n *\n * Thin re-export of the in-house concurrency helpers (ADR D135 — no\n * `p-limit`/`p-map` dependency). Split into its own top-level module so\n * `tsup` builds a dedicated `@theokit/sdk/concurrency` sub-path entry,\n * mirroring the `path-safety` pattern.\n *\n * - `createSemaphore(permits)` — N-permit async-aware counting semaphore.\n * - `mapWithConcurrency(items, concurrency, fn, opts?)` — ordered bounded map.\n */\n\nimport {\n type AsyncSemaphore,\n createSemaphore,\n} from \"./internal/runtime/concurrency/async-semaphore.js\";\n\nexport type { AsyncSemaphore };\n\n/** SE36 — `Semaphore.create` replaces `createSemaphore` (ADR 0015). @public */\nexport class Semaphore {\n private constructor() {}\n static create(permits: number): AsyncSemaphore {\n return createSemaphore(permits);\n }\n}\nexport { mapWithConcurrency } from \"./internal/runtime/concurrency/map-with-concurrency.js\";\n"]}
|
package/dist/create-skill.d.ts
CHANGED
|
@@ -8,9 +8,9 @@
|
|
|
8
8
|
* not bodies — inline and file skills are symmetric there). Inline skills override file skills on a
|
|
9
9
|
* name conflict (mirrors the subagents-loader precedent).
|
|
10
10
|
*/
|
|
11
|
-
import type { Skill } from "./internal/runtime/skills/discover-skills.js";
|
|
11
|
+
import type { Skill as SkillShape } from "./internal/runtime/skills/discover-skills.js";
|
|
12
12
|
/** A code-defined skill (from {@link createSkill}) — a {@link Skill} plus its inline body. */
|
|
13
|
-
export interface InlineSkill extends
|
|
13
|
+
export interface InlineSkill extends SkillShape {
|
|
14
14
|
/** The skill body/instructions (inline skills carry it here instead of a SKILL.md file). */
|
|
15
15
|
instructions: string;
|
|
16
16
|
/**
|
|
@@ -30,8 +30,8 @@ export interface CreateSkillSpec {
|
|
|
30
30
|
/** SE21 — supporting documents (filename → content), like a filesystem skill's `references/`. */
|
|
31
31
|
references?: Record<string, string>;
|
|
32
32
|
}
|
|
33
|
-
/**
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
33
|
+
/** SE36 — `Skill.create` replaces `createSkill` (ADR 0015). @public */
|
|
34
|
+
export declare class Skill {
|
|
35
|
+
private constructor();
|
|
36
|
+
static create(spec: CreateSkillSpec): InlineSkill;
|
|
37
|
+
}
|
|
@@ -804,7 +804,7 @@ interface ConversationStorageAdapter {
|
|
|
804
804
|
*
|
|
805
805
|
* @public
|
|
806
806
|
*/
|
|
807
|
-
interface Skill {
|
|
807
|
+
interface Skill$1 {
|
|
808
808
|
name: string;
|
|
809
809
|
description: string;
|
|
810
810
|
/** Absolute path to the discovered `SKILL.md`. */
|
|
@@ -825,7 +825,7 @@ interface Skill {
|
|
|
825
825
|
*/
|
|
826
826
|
|
|
827
827
|
/** A code-defined skill (from {@link createSkill}) — a {@link Skill} plus its inline body. */
|
|
828
|
-
interface InlineSkill extends Skill {
|
|
828
|
+
interface InlineSkill extends Skill$1 {
|
|
829
829
|
/** The skill body/instructions (inline skills carry it here instead of a SKILL.md file). */
|
|
830
830
|
instructions: string;
|
|
831
831
|
/**
|
|
@@ -845,11 +845,11 @@ interface CreateSkillSpec {
|
|
|
845
845
|
/** SE21 — supporting documents (filename → content), like a filesystem skill's `references/`. */
|
|
846
846
|
references?: Record<string, string>;
|
|
847
847
|
}
|
|
848
|
-
/**
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
848
|
+
/** SE36 — `Skill.create` replaces `createSkill` (ADR 0015). @public */
|
|
849
|
+
declare class Skill {
|
|
850
|
+
private constructor();
|
|
851
|
+
static create(spec: CreateSkillSpec): InlineSkill;
|
|
852
|
+
}
|
|
853
853
|
|
|
854
854
|
/**
|
|
855
855
|
* Context manager backend.
|
|
@@ -1162,6 +1162,13 @@ interface BasePlugin {
|
|
|
1162
1162
|
name: string;
|
|
1163
1163
|
version: string;
|
|
1164
1164
|
}
|
|
1165
|
+
/**
|
|
1166
|
+
* Identity helper for plugin authors. TS-only convenience — preserves
|
|
1167
|
+
* inferred type without forcing manual `Plugin` annotation.
|
|
1168
|
+
*
|
|
1169
|
+
* @public
|
|
1170
|
+
*/
|
|
1171
|
+
declare function definePlugin<P extends Plugin>(p: P): P;
|
|
1165
1172
|
type Plugin = (BasePlugin & {
|
|
1166
1173
|
kind: "general";
|
|
1167
1174
|
register: (ctx: PluginContext) => void | Promise<void>;
|
|
@@ -1172,13 +1179,10 @@ type Plugin = (BasePlugin & {
|
|
|
1172
1179
|
kind: "memory";
|
|
1173
1180
|
createProvider: MemoryProviderFactory;
|
|
1174
1181
|
});
|
|
1175
|
-
/**
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
* @public
|
|
1180
|
-
*/
|
|
1181
|
-
declare function definePlugin<P extends Plugin>(p: P): P;
|
|
1182
|
+
/** SE36 — `Plugin.create` replaces `definePlugin` (ADR 0015). Const-companion (the `Plugin` type alias blocks a class of the same name); `create` is the generic `definePlugin`. @public */
|
|
1183
|
+
declare const Plugin: {
|
|
1184
|
+
create: typeof definePlugin;
|
|
1185
|
+
};
|
|
1182
1186
|
|
|
1183
1187
|
/**
|
|
1184
1188
|
* Which on-disk settings layers a local agent loads.
|
|
@@ -2683,4 +2687,4 @@ declare class Cron {
|
|
|
2683
2687
|
static status(_options?: CronStartOptions): Promise<CronSchedulerStatus>;
|
|
2684
2688
|
}
|
|
2685
2689
|
|
|
2686
|
-
export { type CronOperationOptions as $, type AgentOptions as A, type BudgetTracker as B, type CloudOptions as C, type BudgetCheck as D, type BudgetTotal as E, type BudgetUsageEvent as F, type GetAgentOptions as G, type CloudEnv as H, type InlineSkill as I, type CloudRepo as J, type ContextBudget as K, type LocalOptions as L, type MemorySettings as M, type ContextManagerKind as N, type ObjectiveRecord as O, type ProviderRoutingSettings as P, type ContextSnapshot as Q, type ContextSource as R, type SystemPromptResolver as S, type ContextSourceStatus as T, type CreateSkillSpec as U, Cron as V, type CronCreateOptions as W, type CronGetOptions as X, type CronJob as Y, type CronJobStatus as Z, type CronListOptions as _, type AgentDefinition as a, type CronRunOptions as a0, type CronRuntime as a1, type CronSchedulerStatus as a2, type CronStartOptions as a3, type DurableGoalOptions as a4, type GoalEvent as a5, type GoalOptions as a6, type GoalResult as a7, type HookName as a8, type InvalidateCacheOptions as a9, type SDKPluginMetadata as aA, type SDKProvidersManager as aB, type SettingSource as aC,
|
|
2690
|
+
export { type CronOperationOptions as $, type AgentOptions as A, type BudgetTracker as B, type CloudOptions as C, type BudgetCheck as D, type BudgetTotal as E, type BudgetUsageEvent as F, type GetAgentOptions as G, type CloudEnv as H, type InlineSkill as I, type CloudRepo as J, type ContextBudget as K, type LocalOptions as L, type MemorySettings as M, type ContextManagerKind as N, type ObjectiveRecord as O, type ProviderRoutingSettings as P, type ContextSnapshot as Q, type ContextSource as R, type SystemPromptResolver as S, type ContextSourceStatus as T, type CreateSkillSpec as U, Cron as V, type CronCreateOptions as W, type CronGetOptions as X, type CronJob as Y, type CronJobStatus as Z, type CronListOptions as _, type AgentDefinition as a, type CronRunOptions as a0, type CronRuntime as a1, type CronSchedulerStatus as a2, type CronStartOptions as a3, type DurableGoalOptions as a4, type GoalEvent as a5, type GoalOptions as a6, type GoalResult as a7, type HookName as a8, type InvalidateCacheOptions as a9, type SDKPluginMetadata as aA, type SDKProvidersManager as aB, type SettingSource as aC, Skill as aD, type SkillsResolver as aE, type SkillsResolverContext as aF, type SystemPromptContext as aG, type SystemPromptMemoryFact as aH, type SystemPromptSkillRef as aI, type TelemetrySettings as aJ, type MemoryAdapter as aa, type MemoryAdapterCapabilities as ab, type MemoryContext as ac, type MemoryFact as ad, type MemoryProviderHandle as ae, type MemoryProviderInitOptions as af, type MemoryRevision as ag, type MemoryToolSchema as ah, type MemoryTurnMessage as ai, type ObjectiveStatus as aj, type PersonalityPreset as ak, type PluginContext as al, type PostAssistantReplyContext as am, type PreToolCallContext as an, type PreUserSendContext as ao, type PreUserSendResult as ap, type ProviderCapability as aq, type ProviderRoute as ar, type RecordSessionSummaryArgs as as, type ResolvedProviderRoute as at, type RunUntilIterator as au, type SDKAgentPlugins as av, type SDKAgentSkillDetail as aw, type SDKAgentSkills as ax, type SDKArtifact as ay, type SDKContextManager as az, type ContextSettings as b, type PluginsSettings as c, type SkillsSettings as d, type SDKAgent as e, type ListAgentsOptions as f, type ListResult as g, type SDKAgentInfo as h, type ListRunsOptions as i, type GetRunOptions as j, type AgentOperationOptions as k, type ProviderProfile as l, Plugin as m, type ConversationStorageAdapter as n, type StoredMessage as o, type SessionMeta as p, type SessionMetaPatch as q, type MemoryProvider as r, type MemoryId as s, type PreToolCallDecision as t, type StepResult as u, type SDKProvider as v, type ActiveMemoryPassArgs as w, type ActiveMemoryPassResult as x, type AgentGoalConfig as y, type AgentMemory as z };
|
|
@@ -804,7 +804,7 @@ interface ConversationStorageAdapter {
|
|
|
804
804
|
*
|
|
805
805
|
* @public
|
|
806
806
|
*/
|
|
807
|
-
interface Skill {
|
|
807
|
+
interface Skill$1 {
|
|
808
808
|
name: string;
|
|
809
809
|
description: string;
|
|
810
810
|
/** Absolute path to the discovered `SKILL.md`. */
|
|
@@ -825,7 +825,7 @@ interface Skill {
|
|
|
825
825
|
*/
|
|
826
826
|
|
|
827
827
|
/** A code-defined skill (from {@link createSkill}) — a {@link Skill} plus its inline body. */
|
|
828
|
-
interface InlineSkill extends Skill {
|
|
828
|
+
interface InlineSkill extends Skill$1 {
|
|
829
829
|
/** The skill body/instructions (inline skills carry it here instead of a SKILL.md file). */
|
|
830
830
|
instructions: string;
|
|
831
831
|
/**
|
|
@@ -845,11 +845,11 @@ interface CreateSkillSpec {
|
|
|
845
845
|
/** SE21 — supporting documents (filename → content), like a filesystem skill's `references/`. */
|
|
846
846
|
references?: Record<string, string>;
|
|
847
847
|
}
|
|
848
|
-
/**
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
848
|
+
/** SE36 — `Skill.create` replaces `createSkill` (ADR 0015). @public */
|
|
849
|
+
declare class Skill {
|
|
850
|
+
private constructor();
|
|
851
|
+
static create(spec: CreateSkillSpec): InlineSkill;
|
|
852
|
+
}
|
|
853
853
|
|
|
854
854
|
/**
|
|
855
855
|
* Context manager backend.
|
|
@@ -1162,6 +1162,13 @@ interface BasePlugin {
|
|
|
1162
1162
|
name: string;
|
|
1163
1163
|
version: string;
|
|
1164
1164
|
}
|
|
1165
|
+
/**
|
|
1166
|
+
* Identity helper for plugin authors. TS-only convenience — preserves
|
|
1167
|
+
* inferred type without forcing manual `Plugin` annotation.
|
|
1168
|
+
*
|
|
1169
|
+
* @public
|
|
1170
|
+
*/
|
|
1171
|
+
declare function definePlugin<P extends Plugin>(p: P): P;
|
|
1165
1172
|
type Plugin = (BasePlugin & {
|
|
1166
1173
|
kind: "general";
|
|
1167
1174
|
register: (ctx: PluginContext) => void | Promise<void>;
|
|
@@ -1172,13 +1179,10 @@ type Plugin = (BasePlugin & {
|
|
|
1172
1179
|
kind: "memory";
|
|
1173
1180
|
createProvider: MemoryProviderFactory;
|
|
1174
1181
|
});
|
|
1175
|
-
/**
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
* @public
|
|
1180
|
-
*/
|
|
1181
|
-
declare function definePlugin<P extends Plugin>(p: P): P;
|
|
1182
|
+
/** SE36 — `Plugin.create` replaces `definePlugin` (ADR 0015). Const-companion (the `Plugin` type alias blocks a class of the same name); `create` is the generic `definePlugin`. @public */
|
|
1183
|
+
declare const Plugin: {
|
|
1184
|
+
create: typeof definePlugin;
|
|
1185
|
+
};
|
|
1182
1186
|
|
|
1183
1187
|
/**
|
|
1184
1188
|
* Which on-disk settings layers a local agent loads.
|
|
@@ -2683,4 +2687,4 @@ declare class Cron {
|
|
|
2683
2687
|
static status(_options?: CronStartOptions): Promise<CronSchedulerStatus>;
|
|
2684
2688
|
}
|
|
2685
2689
|
|
|
2686
|
-
export { type CronOperationOptions as $, type AgentOptions as A, type BudgetTracker as B, type CloudOptions as C, type BudgetCheck as D, type BudgetTotal as E, type BudgetUsageEvent as F, type GetAgentOptions as G, type CloudEnv as H, type InlineSkill as I, type CloudRepo as J, type ContextBudget as K, type LocalOptions as L, type MemorySettings as M, type ContextManagerKind as N, type ObjectiveRecord as O, type ProviderRoutingSettings as P, type ContextSnapshot as Q, type ContextSource as R, type SystemPromptResolver as S, type ContextSourceStatus as T, type CreateSkillSpec as U, Cron as V, type CronCreateOptions as W, type CronGetOptions as X, type CronJob as Y, type CronJobStatus as Z, type CronListOptions as _, type AgentDefinition as a, type CronRunOptions as a0, type CronRuntime as a1, type CronSchedulerStatus as a2, type CronStartOptions as a3, type DurableGoalOptions as a4, type GoalEvent as a5, type GoalOptions as a6, type GoalResult as a7, type HookName as a8, type InvalidateCacheOptions as a9, type SDKPluginMetadata as aA, type SDKProvidersManager as aB, type SettingSource as aC,
|
|
2690
|
+
export { type CronOperationOptions as $, type AgentOptions as A, type BudgetTracker as B, type CloudOptions as C, type BudgetCheck as D, type BudgetTotal as E, type BudgetUsageEvent as F, type GetAgentOptions as G, type CloudEnv as H, type InlineSkill as I, type CloudRepo as J, type ContextBudget as K, type LocalOptions as L, type MemorySettings as M, type ContextManagerKind as N, type ObjectiveRecord as O, type ProviderRoutingSettings as P, type ContextSnapshot as Q, type ContextSource as R, type SystemPromptResolver as S, type ContextSourceStatus as T, type CreateSkillSpec as U, Cron as V, type CronCreateOptions as W, type CronGetOptions as X, type CronJob as Y, type CronJobStatus as Z, type CronListOptions as _, type AgentDefinition as a, type CronRunOptions as a0, type CronRuntime as a1, type CronSchedulerStatus as a2, type CronStartOptions as a3, type DurableGoalOptions as a4, type GoalEvent as a5, type GoalOptions as a6, type GoalResult as a7, type HookName as a8, type InvalidateCacheOptions as a9, type SDKPluginMetadata as aA, type SDKProvidersManager as aB, type SettingSource as aC, Skill as aD, type SkillsResolver as aE, type SkillsResolverContext as aF, type SystemPromptContext as aG, type SystemPromptMemoryFact as aH, type SystemPromptSkillRef as aI, type TelemetrySettings as aJ, type MemoryAdapter as aa, type MemoryAdapterCapabilities as ab, type MemoryContext as ac, type MemoryFact as ad, type MemoryProviderHandle as ae, type MemoryProviderInitOptions as af, type MemoryRevision as ag, type MemoryToolSchema as ah, type MemoryTurnMessage as ai, type ObjectiveStatus as aj, type PersonalityPreset as ak, type PluginContext as al, type PostAssistantReplyContext as am, type PreToolCallContext as an, type PreUserSendContext as ao, type PreUserSendResult as ap, type ProviderCapability as aq, type ProviderRoute as ar, type RecordSessionSummaryArgs as as, type ResolvedProviderRoute as at, type RunUntilIterator as au, type SDKAgentPlugins as av, type SDKAgentSkillDetail as aw, type SDKAgentSkills as ax, type SDKArtifact as ay, type SDKContextManager as az, type ContextSettings as b, type PluginsSettings as c, type SkillsSettings as d, type SDKAgent as e, type ListAgentsOptions as f, type ListResult as g, type SDKAgentInfo as h, type ListRunsOptions as i, type GetRunOptions as j, type AgentOperationOptions as k, type ProviderProfile as l, Plugin as m, type ConversationStorageAdapter as n, type StoredMessage as o, type SessionMeta as p, type SessionMetaPatch as q, type MemoryProvider as r, type MemoryId as s, type PreToolCallDecision as t, type StepResult as u, type SDKProvider as v, type ActiveMemoryPassArgs as w, type ActiveMemoryPassResult as x, type AgentGoalConfig as y, type AgentMemory as z };
|
package/dist/cron.d.cts
CHANGED