@graphorin/core 0.6.1 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. package/CHANGELOG.md +82 -0
  2. package/README.md +8 -5
  3. package/dist/channels/index.d.ts +2 -2
  4. package/dist/channels/index.js +2 -2
  5. package/dist/channels/pause.d.ts +47 -2
  6. package/dist/channels/pause.d.ts.map +1 -1
  7. package/dist/channels/pause.js +62 -2
  8. package/dist/channels/pause.js.map +1 -1
  9. package/dist/contracts/checkpoint-store.d.ts +97 -1
  10. package/dist/contracts/checkpoint-store.d.ts.map +1 -1
  11. package/dist/contracts/checkpoint-store.js.map +1 -1
  12. package/dist/contracts/index.d.ts +5 -5
  13. package/dist/contracts/index.js +2 -1
  14. package/dist/contracts/memory-store.d.ts +59 -2
  15. package/dist/contracts/memory-store.d.ts.map +1 -1
  16. package/dist/contracts/provider.d.ts +20 -6
  17. package/dist/contracts/provider.d.ts.map +1 -1
  18. package/dist/contracts/session-store.d.ts +10 -2
  19. package/dist/contracts/session-store.d.ts.map +1 -1
  20. package/dist/contracts/tool.d.ts +75 -1
  21. package/dist/contracts/tool.d.ts.map +1 -1
  22. package/dist/contracts/tool.js +57 -0
  23. package/dist/contracts/tool.js.map +1 -0
  24. package/dist/contracts/tracer.d.ts +53 -5
  25. package/dist/contracts/tracer.d.ts.map +1 -1
  26. package/dist/contracts/tracer.js.map +1 -1
  27. package/dist/index.d.ts +9 -7
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +5 -5
  30. package/dist/package.js +1 -1
  31. package/dist/package.js.map +1 -1
  32. package/dist/types/agent-event-wire.d.ts +74 -0
  33. package/dist/types/agent-event-wire.d.ts.map +1 -0
  34. package/dist/types/agent-event-wire.js +130 -0
  35. package/dist/types/agent-event-wire.js.map +1 -0
  36. package/dist/types/agent-event.d.ts +48 -6
  37. package/dist/types/agent-event.d.ts.map +1 -1
  38. package/dist/types/index.d.ts +3 -2
  39. package/dist/types/index.js +2 -1
  40. package/dist/types/memory.d.ts +11 -0
  41. package/dist/types/memory.d.ts.map +1 -1
  42. package/dist/types/run.d.ts +86 -4
  43. package/dist/types/run.d.ts.map +1 -1
  44. package/dist/types/run.js.map +1 -1
  45. package/dist/types/tool.d.ts +10 -0
  46. package/dist/types/tool.d.ts.map +1 -1
  47. package/dist/types/usage.d.ts +11 -1
  48. package/dist/types/usage.d.ts.map +1 -1
  49. package/dist/types/usage.js.map +1 -1
  50. package/dist/utils/binary-json.d.ts +165 -0
  51. package/dist/utils/binary-json.d.ts.map +1 -0
  52. package/dist/utils/binary-json.js +240 -0
  53. package/dist/utils/binary-json.js.map +1 -0
  54. package/dist/utils/index.d.ts +2 -1
  55. package/dist/utils/index.js +2 -1
  56. package/dist/utils/validation.d.ts +10 -1
  57. package/dist/utils/validation.d.ts.map +1 -1
  58. package/dist/utils/validation.js +1 -1
  59. package/dist/utils/validation.js.map +1 -1
  60. package/package.json +9 -7
  61. package/src/channels/channels.ts +206 -0
  62. package/src/channels/directive.ts +41 -0
  63. package/src/channels/dispatch.ts +37 -0
  64. package/src/channels/durable.ts +151 -0
  65. package/src/channels/index.ts +62 -0
  66. package/src/channels/pause.ts +216 -0
  67. package/src/contracts/auth-token-store.ts +42 -0
  68. package/src/contracts/checkpoint-store.ts +256 -0
  69. package/src/contracts/embedder.ts +42 -0
  70. package/src/contracts/eval-scorer.ts +44 -0
  71. package/src/contracts/index.ts +112 -0
  72. package/src/contracts/local-provider-trust.ts +33 -0
  73. package/src/contracts/logger.ts +61 -0
  74. package/src/contracts/memory-store.ts +187 -0
  75. package/src/contracts/oauth-server-store.ts +78 -0
  76. package/src/contracts/preferred-model.ts +56 -0
  77. package/src/contracts/provider.ts +316 -0
  78. package/src/contracts/reasoning-retention.ts +52 -0
  79. package/src/contracts/redaction-validator.ts +56 -0
  80. package/src/contracts/sandbox.ts +70 -0
  81. package/src/contracts/secret-ref.ts +22 -0
  82. package/src/contracts/secret-value.ts +117 -0
  83. package/src/contracts/secrets-store.ts +90 -0
  84. package/src/contracts/session-store.ts +163 -0
  85. package/src/contracts/token-counter.ts +23 -0
  86. package/src/contracts/tool.ts +397 -0
  87. package/src/contracts/tracer.ts +219 -0
  88. package/src/contracts/trigger-store.ts +40 -0
  89. package/src/index.ts +23 -0
  90. package/src/types/agent-event-wire.ts +193 -0
  91. package/src/types/agent-event.ts +579 -0
  92. package/src/types/handoff.ts +111 -0
  93. package/src/types/index.ts +148 -0
  94. package/src/types/memory.ts +427 -0
  95. package/src/types/message.ts +174 -0
  96. package/src/types/run.ts +312 -0
  97. package/src/types/sensitivity.ts +35 -0
  98. package/src/types/session-scope.ts +18 -0
  99. package/src/types/stop-condition.ts +108 -0
  100. package/src/types/tool-call.ts +24 -0
  101. package/src/types/tool.ts +324 -0
  102. package/src/types/usage.ts +120 -0
  103. package/src/types/workflow-event.ts +132 -0
  104. package/src/utils/assert-never.ts +24 -0
  105. package/src/utils/async-context.ts +55 -0
  106. package/src/utils/binary-json.ts +425 -0
  107. package/src/utils/hash.ts +122 -0
  108. package/src/utils/index.ts +57 -0
  109. package/src/utils/streams.ts +233 -0
  110. package/src/utils/validation.ts +82 -0
@@ -0,0 +1,112 @@
1
+ /**
2
+ * Cross-package contracts for the Graphorin framework.
3
+ *
4
+ * @packageDocumentation
5
+ */
6
+
7
+ export type { AuthTokenRecord, AuthTokenStore } from './auth-token-store.js';
8
+ export type {
9
+ Checkpoint,
10
+ CheckpointId,
11
+ CheckpointMetadata,
12
+ CheckpointPutOptions,
13
+ CheckpointStore,
14
+ CheckpointStoreExt,
15
+ CheckpointTuple,
16
+ ListOptions,
17
+ PendingWrite,
18
+ PruneThreadsOptions,
19
+ } from './checkpoint-store.js';
20
+ export { CheckpointConflictError } from './checkpoint-store.js';
21
+
22
+ export type { EmbedderProvider, EmbedOptions } from './embedder.js';
23
+ export type { EvalSample, EvalScore, EvalScorer } from './eval-scorer.js';
24
+ export type { LocalProviderTrust, OllamaTrust } from './local-provider-trust.js';
25
+ export type { LogFields, Logger, LogLevel } from './logger.js';
26
+ export { NOOP_LOGGER } from './logger.js';
27
+ export type {
28
+ EpisodicMemoryStore,
29
+ MemoryStore,
30
+ MemoryStoreExt,
31
+ MessageRef,
32
+ ProceduralMemoryStore,
33
+ SemanticMemoryStore,
34
+ SessionListOptions,
35
+ SessionMemoryStore,
36
+ SessionMessageWithMetadata,
37
+ SharedMemoryStore,
38
+ WorkingMemoryStore,
39
+ } from './memory-store.js';
40
+ export type { OAuthServerRecord, OAuthServerStore } from './oauth-server-store.js';
41
+ export type { ModelHint, ModelSpec, ProviderLike } from './preferred-model.js';
42
+ export { MODEL_HINTS } from './preferred-model.js';
43
+ export type {
44
+ ComposeProviderMiddleware,
45
+ FinishReason,
46
+ OutputSpec,
47
+ Provider,
48
+ ProviderCachePolicy,
49
+ ProviderCapabilities,
50
+ ProviderError,
51
+ ProviderErrorKind,
52
+ ProviderEvent,
53
+ ProviderMiddleware,
54
+ ProviderRequest,
55
+ ProviderRequestMetadata,
56
+ ProviderResponse,
57
+ ResponseMetadata,
58
+ ToolChoice,
59
+ ToolDefinition,
60
+ ToolDefinitionExample,
61
+ } from './provider.js';
62
+ export type { ReasoningContract, ReasoningRetention } from './reasoning-retention.js';
63
+ export type { RedactionInput, RedactionOutput, RedactionValidator } from './redaction-validator.js';
64
+ export type { Sandbox, SandboxCode, SandboxResult, SandboxRunOptions } from './sandbox.js';
65
+ export type { SecretRef } from './secret-ref.js';
66
+ export type { SecretValue, SecretValueOptions, SecretValueStatic } from './secret-value.js';
67
+ export { NODEJS_INSPECT_CUSTOM, SECRET_VALUE_BRAND } from './secret-value.js';
68
+ export type {
69
+ SecretMetadata,
70
+ SecretResolver,
71
+ SecretResolverContext,
72
+ SecretsSetOptions,
73
+ SecretsStore,
74
+ } from './secrets-store.js';
75
+ export type {
76
+ AgentRegistryEntry,
77
+ SessionAuditEntry,
78
+ SessionMetadata,
79
+ SessionStore,
80
+ SessionStoreExt,
81
+ SessionWorkflowRun,
82
+ } from './session-store.js';
83
+ export type { TokenCounter } from './token-counter.js';
84
+ export type {
85
+ AnyTool,
86
+ ResolvedTool,
87
+ Tool,
88
+ ToolExample,
89
+ ToolExecutionContext,
90
+ ToolReturn,
91
+ ToolSecretsAccessor,
92
+ } from './tool.js';
93
+ export {
94
+ isToolReturnEnvelope,
95
+ isUnbrandedToolReturn,
96
+ TOOL_RETURN_BRAND,
97
+ toolReturn,
98
+ } from './tool.js';
99
+ export type {
100
+ AddEventOptions,
101
+ AISpan,
102
+ CustomSpanType,
103
+ KnownSpanType,
104
+ SpanAttributes,
105
+ SpanAttributeValue,
106
+ SpanStatus,
107
+ SpanType,
108
+ StartSpanOptions,
109
+ Tracer,
110
+ } from './tracer.js';
111
+ export { NOOP_TRACER } from './tracer.js';
112
+ export type { TriggerState, TriggerStore } from './trigger-store.js';
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Trust class assigned to a local-LLM provider based on the
3
+ * configured `baseUrl`. The classifier dispatcher lives in
4
+ * `@graphorin/provider/trust/classify-local-provider.ts`; the literal
5
+ * union is hoisted here so consumers (security policy, observability,
6
+ * prompt redaction) can type-check against it without depending on
7
+ * `@graphorin/provider`.
8
+ *
9
+ * Tier semantics:
10
+ *
11
+ * - `'loopback'` - `localhost` / `127.0.0.0/8` / `::1` /
12
+ * `unix:///path` (or any in-process adapter that has no `baseUrl`).
13
+ * Same trust boundary as the host process.
14
+ * - `'private'` - RFC 1918 (`10/8`, `172.16/12`,
15
+ * `192.168/16`); RFC 6598 CGNAT (`100.64/10`); link-local
16
+ * (`169.254/16`, `fe80::/10`); `*.local` / `*.lan` / `*.internal` /
17
+ * `*.home.arpa`.
18
+ * - `'public-tls'` - public IP / hostname AND `https://`.
19
+ * - `'public-cleartext'` - public IP / hostname AND `http://`. Adapters
20
+ * refuse to start unless explicitly overridden.
21
+ *
22
+ * @stable
23
+ */
24
+ export type LocalProviderTrust = 'loopback' | 'private' | 'public-tls' | 'public-cleartext';
25
+
26
+ /**
27
+ * Legacy alias preserved for downstream packages that still import the
28
+ * Ollama-specific name. Removed in v0.2 per the legacy-sugar
29
+ * deprecation policy.
30
+ *
31
+ * @deprecated Use {@link LocalProviderTrust} instead. Removed in v0.2.
32
+ */
33
+ export type OllamaTrust = LocalProviderTrust;
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Severity levels supported by the project logger. Mirrors the canonical
3
+ * `trace < debug < info < warn < error` hierarchy used by every common
4
+ * structured logger.
5
+ *
6
+ * @stable
7
+ */
8
+ export type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error';
9
+
10
+ /**
11
+ * Free-form structured fields that accompany a log record. Values must be
12
+ * JSON-serializable; concrete loggers redact `SecretValue` and other
13
+ * sensitive shapes per the framework's redaction policy.
14
+ *
15
+ * @stable
16
+ */
17
+ export type LogFields = Readonly<Record<string, unknown>>;
18
+
19
+ /**
20
+ * Pluggable logger contract consumed by every `@graphorin/*` runtime
21
+ * package. The concrete implementation lives in `@graphorin/observability`
22
+ * - declaring the interface here keeps level-zero packages free of an
23
+ * observability dependency.
24
+ *
25
+ * Loggers are intentionally **structured** and **side-effect-free** in the
26
+ * type contract: the `info(msg, fields?)` signature is a hint, not a
27
+ * mandate to actually emit anything. Implementations may sample, drop, or
28
+ * batch.
29
+ *
30
+ * @stable
31
+ */
32
+ export interface Logger {
33
+ trace(message: string, fields?: LogFields): void;
34
+ debug(message: string, fields?: LogFields): void;
35
+ info(message: string, fields?: LogFields): void;
36
+ warn(message: string, fields?: LogFields): void;
37
+ error(message: string, fields?: LogFields): void;
38
+ /**
39
+ * Return a child logger with `fields` merged into every record's
40
+ * structured payload. Useful for binding `runId` / `sessionId` /
41
+ * `agentId` once at the top of a request.
42
+ */
43
+ child(fields: LogFields): Logger;
44
+ }
45
+
46
+ /**
47
+ * Minimal no-op logger. Useful as a typed default when downstream code
48
+ * needs a non-null `Logger` without taking the observability dependency.
49
+ *
50
+ * @stable
51
+ */
52
+ export const NOOP_LOGGER: Logger = {
53
+ trace(): void {},
54
+ debug(): void {},
55
+ info(): void {},
56
+ warn(): void {},
57
+ error(): void {},
58
+ child(): Logger {
59
+ return NOOP_LOGGER;
60
+ },
61
+ };
@@ -0,0 +1,187 @@
1
+ import type {
2
+ Block,
3
+ Episode,
4
+ Fact,
5
+ MemoryHit,
6
+ MemoryRecord,
7
+ MemorySearchOptions,
8
+ Rule,
9
+ } from '../types/memory.js';
10
+ import type { Message } from '../types/message.js';
11
+ import type { SessionScope } from '../types/session-scope.js';
12
+
13
+ /**
14
+ * Persistent storage interface for the six memory tiers. Implementations
15
+ * live in the storage adapter packages (`@graphorin/store-sqlite` is the
16
+ * default).
17
+ *
18
+ * Sub-namespaces map 1:1 to the six tiers so each implementation can
19
+ * pick its own physical layout (one big table, six tables, mixed) while
20
+ * preserving append-only semantics - soft-delete only.
21
+ *
22
+ * **Baseline vs full adapter (W-048).** This interface is the MINIMUM a
23
+ * third-party adapter must implement; `@graphorin/memory` accepts it and
24
+ * degrades gracefully (vector search, decay, consolidation, insights,
25
+ * graph expansion, conflict audit switch off where the surface is
26
+ * absent). Full feature parity with `@graphorin/store-sqlite` (asOf
27
+ * reads, vector KNN, decay signals, insights, entity graph, conflicts,
28
+ * consolidator state/DLQ) is described by `MemoryStoreAdapter` and the
29
+ * `*MemoryStoreExt` interfaces exported from the root of
30
+ * `@graphorin/memory`. Every Ext addition over the six tier namespaces
31
+ * is optional BY CONTRACT - a type test in `@graphorin/memory` pins
32
+ * `MemoryStore extends MemoryStoreAdapter`, so a core-only adapter can
33
+ * never stop compiling.
34
+ *
35
+ * @stable
36
+ */
37
+ export interface MemoryStore {
38
+ readonly working: WorkingMemoryStore;
39
+ readonly session: SessionMemoryStore;
40
+ readonly episodic: EpisodicMemoryStore;
41
+ readonly semantic: SemanticMemoryStore;
42
+ readonly procedural: ProceduralMemoryStore;
43
+ readonly shared: SharedMemoryStore;
44
+
45
+ /** Initialize / migrate the underlying storage. Idempotent. */
46
+ init(): Promise<void>;
47
+ /** Cleanly close any underlying handles. Idempotent. */
48
+ close(): Promise<void>;
49
+ }
50
+
51
+ /**
52
+ * Maintenance extension over {@link MemoryStore} (W-066), mirroring
53
+ * the `SessionStoreExt` precedent: capabilities the sqlite adapter
54
+ * guarantees but a custom `MemoryStore` is not obliged to implement.
55
+ * The base contract is unchanged - existing implementations keep
56
+ * compiling.
57
+ *
58
+ * @stable
59
+ */
60
+ export interface MemoryStoreExt extends MemoryStore {
61
+ /**
62
+ * Delete `memory_history` rows older than the given AGE in
63
+ * milliseconds. The argument is an AGE (the implementation computes
64
+ * `cutoff = now - olderThanMs`), never an epoch cutoff - passing an
65
+ * epoch value would compute a nonsense cutoff far in the past and
66
+ * silently prune nothing. Returns the number of rows removed.
67
+ * History grows by design (every supersede / quarantine transition
68
+ * appends) and `purge()` already scrubs sensitive text; this is the
69
+ * storage-cost hygiene lever - nothing prunes automatically.
70
+ */
71
+ pruneHistory(olderThanMs: number): Promise<number>;
72
+ }
73
+
74
+ /** @stable */
75
+ export interface WorkingMemoryStore {
76
+ list(scope: SessionScope): Promise<ReadonlyArray<Block>>;
77
+ get(scope: SessionScope, label: string): Promise<Block | null>;
78
+ upsert(scope: SessionScope, block: Block): Promise<void>;
79
+ delete(scope: SessionScope, label: string, reason?: string): Promise<void>;
80
+ }
81
+
82
+ /**
83
+ * Reference returned by `SessionMemoryStore.push(...)`. Carries the
84
+ * persisted message id and a sequence number for ordering.
85
+ *
86
+ * @stable
87
+ */
88
+ export interface MessageRef {
89
+ readonly messageId: string;
90
+ readonly sequence: number;
91
+ readonly persistedAt: string;
92
+ }
93
+
94
+ /**
95
+ * A stored message paired with its persisted identity (RP-5). The {@link Message}
96
+ * type itself carries no id / timestamp; these come from the store row, so an
97
+ * exporter can preserve message identity + chronology across a round-trip.
98
+ *
99
+ * @stable
100
+ */
101
+ export interface SessionMessageWithMetadata {
102
+ readonly message: Message;
103
+ readonly messageId: string;
104
+ readonly sequence: number;
105
+ readonly createdAt: string;
106
+ }
107
+
108
+ /** @stable */
109
+ export interface SessionMemoryStore {
110
+ push(scope: SessionScope, message: Message): Promise<MessageRef>;
111
+ list(scope: SessionScope, opts?: SessionListOptions): Promise<ReadonlyArray<Message>>;
112
+ /**
113
+ * List messages with their persisted identity (RP-5). Optional: stores that
114
+ * don't implement it fall back to `list` + fabricated ids on the export path.
115
+ */
116
+ listWithMetadata?(
117
+ scope: SessionScope,
118
+ opts?: SessionListOptions,
119
+ ): Promise<ReadonlyArray<SessionMessageWithMetadata>>;
120
+ /**
121
+ * Full-text search over the scoped session messages.
122
+ *
123
+ * Query precedence (W-127): the POSITIONAL `query` parameter is
124
+ * authoritative; when the caller also sets `opts.query` (the field
125
+ * exists because {@link MemorySearchOptions} is shared with the
126
+ * option-object search surfaces), implementations MUST ignore it.
127
+ * The duplication is a known wart: narrowing `opts` to
128
+ * `Omit<MemorySearchOptions, 'query'>` is a candidate for the next
129
+ * major, not a change this line can make compatibly.
130
+ */
131
+ search(
132
+ scope: SessionScope,
133
+ query: string,
134
+ opts?: MemorySearchOptions,
135
+ ): Promise<ReadonlyArray<MemoryHit>>;
136
+ }
137
+
138
+ /** @stable */
139
+ export interface SessionListOptions {
140
+ readonly lastN?: number;
141
+ readonly sinceMessageId?: string;
142
+ readonly agentId?: string;
143
+ readonly role?: 'system' | 'user' | 'assistant' | 'tool';
144
+ }
145
+
146
+ /** @stable */
147
+ export interface EpisodicMemoryStore {
148
+ put(episode: Episode): Promise<void>;
149
+ search(
150
+ scope: SessionScope,
151
+ opts: MemorySearchOptions,
152
+ ): Promise<ReadonlyArray<MemoryHit<Episode>>>;
153
+ get(id: string): Promise<Episode | null>;
154
+ }
155
+
156
+ /** @stable */
157
+ export interface SemanticMemoryStore {
158
+ remember(fact: Fact): Promise<void>;
159
+ search(scope: SessionScope, opts: MemorySearchOptions): Promise<ReadonlyArray<MemoryHit<Fact>>>;
160
+ supersede(oldId: string, newFact: Fact, reason?: string): Promise<void>;
161
+ /**
162
+ * Soft-delete a fact. W-154: when `scope` is supplied, adapters that
163
+ * support tenant isolation MUST treat a fact outside the scope as a
164
+ * deterministic no-op (0 rows changed) - defense in depth so a
165
+ * leaked / cross-user id reaching a mutator cannot touch another
166
+ * user's memory. Omitting `scope` preserves the historical unscoped
167
+ * behaviour (trusted internal callers: consolidator, erasure
168
+ * cascades). The parameter is additive - existing adapter
169
+ * implementations with the narrower arity remain structurally
170
+ * compatible.
171
+ */
172
+ forget(id: string, reason?: string, scope?: SessionScope): Promise<void>;
173
+ }
174
+
175
+ /** @stable */
176
+ export interface ProceduralMemoryStore {
177
+ add(rule: Rule): Promise<void>;
178
+ list(scope: SessionScope): Promise<ReadonlyArray<Rule>>;
179
+ remove(id: string, reason?: string): Promise<void>;
180
+ }
181
+
182
+ /** @stable */
183
+ export interface SharedMemoryStore {
184
+ attach(recordId: string, agentId: string): Promise<void>;
185
+ detach(recordId: string, agentId: string): Promise<void>;
186
+ listFor(agentId: string): Promise<ReadonlyArray<MemoryRecord>>;
187
+ }
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Persisted metadata for an OAuth server registration. The framework
3
+ * never stores raw token material here - the access, refresh, id, and
4
+ * client-secret tokens live in the {@link SecretsStore} and this
5
+ * record only holds the {@link SecretRef} URIs that resolve them.
6
+ *
7
+ * Schema mirrors the canonical `oauth_servers` SQLite table provided
8
+ * by `@graphorin/store-sqlite`.
9
+ *
10
+ * @stable
11
+ */
12
+ export interface OAuthServerRecord {
13
+ /** Stable, human-readable identifier (e.g. `'linear-mcp'`). */
14
+ readonly id: string;
15
+ /** Base URL of the OAuth-protected resource server (e.g. MCP endpoint). */
16
+ readonly serverUrl: string;
17
+ /** Authorization-server `authorization_endpoint`. */
18
+ readonly authorizationEndpoint?: string;
19
+ /** Authorization-server `token_endpoint`. */
20
+ readonly tokenEndpoint?: string;
21
+ /** Authorization-server `registration_endpoint` (RFC 7591). */
22
+ readonly registrationEndpoint?: string;
23
+ /** Authorization-server `revocation_endpoint` (RFC 7009). */
24
+ readonly revocationEndpoint?: string;
25
+ /** Authorization-server `device_authorization_endpoint` (RFC 8628). */
26
+ readonly deviceAuthorizationEndpoint?: string;
27
+ /** Issuer identifier reported in the discovery response. */
28
+ readonly issuer?: string;
29
+ /** Public client identifier; safe to log. */
30
+ readonly clientId: string;
31
+ /** {@link SecretRef} URI for the confidential-client secret. */
32
+ readonly clientSecretRef?: string;
33
+ /** {@link SecretRef} URI for the access token. */
34
+ readonly accessTokenRef?: string;
35
+ /** {@link SecretRef} URI for the refresh token. */
36
+ readonly refreshTokenRef?: string;
37
+ /** {@link SecretRef} URI for the OIDC ID token. */
38
+ readonly idTokenRef?: string;
39
+ /** Epoch milliseconds when the access token stops being valid. */
40
+ readonly expiresAt?: number;
41
+ /** Granted scopes (space-separated string per the OAuth spec). */
42
+ readonly scope?: string;
43
+ /** Redirect URI that was used during the most recent code flow. */
44
+ readonly redirectUri?: string;
45
+ /** Whether the client was registered via Dynamic Client Registration. */
46
+ readonly registeredVia?: 'dcr' | 'manual';
47
+ /** Epoch milliseconds of the last successful refresh. */
48
+ readonly lastRefreshedAt?: number;
49
+ /** Last error string captured from a failing refresh attempt. */
50
+ readonly lastRefreshError?: string;
51
+ /** Epoch milliseconds when the record was first created. */
52
+ readonly createdAt: number;
53
+ /** Epoch milliseconds when the record was last updated. */
54
+ readonly updatedAt: number;
55
+ }
56
+
57
+ /**
58
+ * Pluggable storage for OAuth server registrations + token metadata.
59
+ *
60
+ * The default implementation lives in `@graphorin/store-sqlite`
61
+ * (`oauth_servers` table). `@graphorin/security` ships an in-memory
62
+ * implementation that callers can use until the SQLite-backed store
63
+ * is wired up.
64
+ *
65
+ * @stable
66
+ */
67
+ export interface OAuthServerStore {
68
+ /** Insert or replace the record for `id`. */
69
+ put(record: OAuthServerRecord): Promise<void>;
70
+ /** Read the record for `id`, returning `null` when absent. */
71
+ get(id: string): Promise<OAuthServerRecord | null>;
72
+ /** Snapshot of all stored records, ordered by `id`. */
73
+ list(): Promise<ReadonlyArray<OAuthServerRecord>>;
74
+ /** Apply a partial update to the record at `id`. */
75
+ update(id: string, patch: Partial<OAuthServerRecord>): Promise<OAuthServerRecord>;
76
+ /** Remove the record for `id`. */
77
+ delete(id: string): Promise<void>;
78
+ }
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Cost-tier vocabulary for declaring a preferred model on a tool or
3
+ * agent. Provider-agnostic at the tool-author level; the operator-side
4
+ * `Agent.modelTierMap?: Partial<Record<ModelHint, ModelSpec>>` mapping
5
+ * resolves the hint to a concrete provider per agent.
6
+ *
7
+ * The three tiers describe canonical cloud-provider price-quality
8
+ * envelopes circa 2026:
9
+ *
10
+ * - `'fast'` - low-cost / low-latency / file-navigation /
11
+ * parameter-extraction / low-stakes calls.
12
+ * - `'balanced'` - median cost-quality; the default tier for most
13
+ * tools.
14
+ * - `'smart'` - high-quality / high-stakes / reasoning-heavy /
15
+ * summarization / code-review calls.
16
+ *
17
+ * The vocabulary is Graphorin's own design - no third-party routing-
18
+ * guide attribution leaks into the public surface. Per-provider
19
+ * dispatch lives in `@graphorin/provider/model-tier/classify.ts`.
20
+ *
21
+ * @stable
22
+ */
23
+ export type ModelHint = 'fast' | 'balanced' | 'smart';
24
+
25
+ /**
26
+ * Discriminated string-literal triple for type-level work.
27
+ *
28
+ * @stable
29
+ */
30
+ export const MODEL_HINTS: readonly ModelHint[] = ['fast', 'balanced', 'smart'] as const;
31
+
32
+ /**
33
+ * Forward-declared shape of `Provider`. Re-declared here as a minimal
34
+ * structural type so this module stays cycle-free with respect to
35
+ * `./provider.ts` and downstream consumers can use `ModelSpec` without
36
+ * importing the heavier `Provider` interface.
37
+ *
38
+ * @internal
39
+ */
40
+ export interface ProviderLike {
41
+ readonly name: string;
42
+ readonly modelId: string;
43
+ }
44
+
45
+ /**
46
+ * Concrete provider declaration used at site of the per-tool hint
47
+ * override (Phase 07), the per-tier mapping
48
+ * (`Agent.modelTierMap`, Phase 12), and the agent-level fallback chain
49
+ * (`Agent.fallbackModels`, Phase 12).
50
+ *
51
+ * The shape is unified deliberately so operators learn one thing and
52
+ * use it three places.
53
+ *
54
+ * @stable
55
+ */
56
+ export type ModelSpec = ProviderLike | { readonly provider: ProviderLike; readonly model: string };