@opengeni/codemode 0.4.22 → 0.4.27-canary.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/README.md CHANGED
@@ -5,9 +5,10 @@ catalog from the exact tools admitted to an execution attempt and dispatches
5
5
  both model MCP calls and sandbox Codemode calls through the same opaque tool
6
6
  identities and executors.
7
7
 
8
- The package owns deterministic catalog projection, collision-safe JavaScript
9
- paths, catalog digests, stale-catalog fencing, approval classification, and
10
- result-shape preservation. It does not discover MCP servers, resolve
8
+ The package owns deterministic catalog projection, normalized unique JavaScript
9
+ paths with path-prefix collisions rejected during catalog creation, catalog
10
+ digests, stale-catalog fencing, approval classification, and result-shape
11
+ preservation. It does not discover MCP servers, resolve
11
12
  credentials, persist attempts, or bypass host authorization; callers provide
12
13
  the already-admitted definitions and one authorization hook.
13
14
 
@@ -29,6 +30,31 @@ Generate digest-pinned project declarations from the live attempt catalog with
29
30
  `ogtool declarations opengeni-codemode.d.ts`. Runtime schema validation remains
30
31
  authoritative when a script outlives a catalog generation.
31
32
 
33
+ When submission receives the structured `codemode_catalog_stale` response, the
34
+ client refreshes the catalog once, re-resolves the requested identity or
35
+ namespace path, and retries with the same caller-owned operation id. The API
36
+ emits that code only before creating an operation. Ambiguous transport failures
37
+ may be reconciled by operation id only when the recovered row exactly matches
38
+ the requested attempt scope, catalog digest, tool identity, and canonical
39
+ arguments. Deterministic HTTP conflicts are returned directly and never adopt an
40
+ existing operation during initial admission. Once the API has returned the exact
41
+ operation, a later wake-notification failure resumes from an exact journal read;
42
+ it still rejects any mismatched operation. If that recovery read is unavailable,
43
+ the client returns `outcomeUnknown: true` with the exact operation id so the
44
+ caller can reconcile without generating a second identity. The API also treats
45
+ its post-dispatch journal refresh as best-effort and returns the already-admitted
46
+ operation if that refresh is unavailable. The database serializes concurrent
47
+ first submissions of one operation id, so identical races converge to one
48
+ creation plus one replay rather than a unique-constraint failure. No response
49
+ after operation creation triggers a catalog retry. While a journaled operation
50
+ remains queued or running, the client periodically re-notifies the dispatcher
51
+ with the same operation id. A live claim is not replayed; an expired claim is
52
+ either reclaimed before execution or durably settled outcome-unknown after the
53
+ execution marker. Public
54
+ `CodemodeTransportError` identity and its `codemode_transport_error`
55
+ compatibility code remain unchanged; the stable API detail is exposed as
56
+ `remoteCode`.
57
+
32
58
  The bearer is reread for every request. Namespace paths are resolved against
33
59
  the signed catalog and never parsed into authority from flattened model names.
34
60
  For Browser/Computer work, the authored facade wraps those same atomic entries:
@@ -47,7 +73,21 @@ await app.getByRole("button", { name: "1" }).invoke();
47
73
 
48
74
  Both surfaces return the same durable tool receipts. Human approval, catalog
49
75
  generation, operation idempotency, and outcome-unknown behavior remain enforced
50
- by the shared attempt executor.
76
+ by the shared attempt executor. Catalog, approval, authorization, input
77
+ validation, and argument-sensitive connector-policy prepare complete before the
78
+ durable execution-start marker. The prepared call performs connector begin at
79
+ the executor boundary and completion afterward, so model MCP and Codemode share
80
+ one lifecycle while invalid, blocked, Ask, or unavailable-policy calls settle
81
+ before provider execution. Human-gated model calls additionally require the
82
+ attempt host's exact approved SDK invocation context; calling the environment
83
+ directly cannot bypass approval. The dispatcher keeps its claim alive during
84
+ gateway preparation and reuses a deterministic durable tool-created event if a
85
+ pre-execution claim is reclaimed.
86
+
87
+ `CodemodeCallOptions.signal` cancels only the caller's HTTP/polling observation.
88
+ It does not request server cancellation and cannot prove that an operation
89
+ stopped. The attempt/turn lifecycle remains the only cancellation authority; a
90
+ caller that aborts after submission must reconcile with the same operation id.
51
91
 
52
92
  Editable artifacts use the same path. The object remains in OpenGeni; files are
53
93
  only explicit import/export boundaries:
@@ -1,4 +1,5 @@
1
1
  import type { AttemptToolCatalog } from "@opengeni/contracts";
2
+ import { jsonSchemaToTypeScript } from "@opengeni/tool-gateway";
2
3
  export type GenerateCodemodeDeclarationsOptions = {
3
4
  /** Package whose augmentable CodemodeGeneratedTools interface owns the namespace. */
4
5
  moduleSpecifier?: string;
@@ -8,5 +9,4 @@ export type GenerateCodemodeDeclarationsOptions = {
8
9
  * Types improve authoring only; runtime catalog validation remains authoritative.
9
10
  */
10
11
  export declare function generateCodemodeDeclarations(catalog: AttemptToolCatalog, options?: GenerateCodemodeDeclarationsOptions): string;
11
- /** Honest JSON-Schema-to-TypeScript projection used by declaration generation. */
12
- export declare function jsonSchemaToTypeScript(schema: unknown): string;
12
+ export { jsonSchemaToTypeScript };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { type ValidateFunction } from "ajv";
2
- import { type AttemptToolCall as AttemptToolCallValue, type AttemptToolCaller, type AttemptToolCatalog as AttemptToolCatalogValue, type AttemptToolCatalogEntry as AttemptToolCatalogEntryValue, type AttemptToolIdentity, type AttemptToolResult as AttemptToolResultValue, type CodemodeDispatchAck as CodemodeDispatchAckValue, type CodemodeDispatchRequest as CodemodeDispatchRequestValue, type CodemodeOperation as CodemodeOperationValue } from "@opengeni/contracts";
1
+ import { type AttemptToolCall as AttemptToolCallValue, AttemptToolCaller, type AttemptToolCatalog as AttemptToolCatalogValue, type AttemptToolCatalogEntry as AttemptToolCatalogEntryValue, type AttemptToolIdentity, type AttemptToolResult as AttemptToolResultValue, type CodemodeDispatchAck as CodemodeDispatchAckValue, type CodemodeDispatchRequest as CodemodeDispatchRequestValue, type CodemodeOperation as CodemodeOperationValue } from "@opengeni/contracts";
2
+ import { ToolGateway, ToolGatewayApprovalRequiredError as AttemptToolApprovalRequiredError, ToolGatewayCatalogIntegrityError as AttemptToolCatalogIntegrityError, ToolGatewayCatalogStaleError as AttemptToolCatalogStaleError, ToolGatewayCatalogTooLargeError as AttemptToolCatalogTooLargeError, ToolGatewayInputValidationError as AttemptToolInputValidationError, ToolGatewayOutputValidationError as AttemptToolOutputValidationError, ToolGatewayPathCollisionError as AttemptToolPathCollisionError, ToolGatewayToolNotFoundError as AttemptToolNotFoundError, type PreparedToolGatewayCall, type ToolGatewayCallLifecycle } from "@opengeni/tool-gateway";
3
3
  export type { AttemptToolCatalog, AttemptToolCatalogEntry } from "@opengeni/contracts";
4
4
  export type AttemptToolScope = Pick<AttemptToolCatalogValue, "accountId" | "workspaceId" | "sessionId" | "turnId" | "attemptId" | "executionGeneration">;
5
5
  export type AttemptToolExecutionContext = {
@@ -12,6 +12,8 @@ export type AttemptToolExecutionContext = {
12
12
  export type AttemptToolDefinition = Omit<AttemptToolCatalogEntryValue, "codemodePath"> & {
13
13
  /** Optional human-readable path. Unsafe/colliding segments are normalized. */
14
14
  codemodePath?: readonly string[];
15
+ /** In-process execution lifecycle shared by model MCP and Codemode. */
16
+ lifecycle?: ToolGatewayCallLifecycle;
15
17
  execute: (args: Record<string, unknown>, context: AttemptToolExecutionContext) => Promise<AttemptToolResultValue> | AttemptToolResultValue;
16
18
  };
17
19
  export type AttemptToolAuthorization = (input: {
@@ -24,6 +26,11 @@ export type CreateAttemptToolEnvironmentInput = {
24
26
  definitions: readonly AttemptToolDefinition[];
25
27
  createdAt?: Date;
26
28
  authorize?: AttemptToolAuthorization;
29
+ /** Host-only approval projection for one exact model invocation. */
30
+ confirmModelApproval?: (input: {
31
+ modelName: string;
32
+ subjectId: string;
33
+ }) => boolean;
27
34
  };
28
35
  export type ModelAttemptToolCall = {
29
36
  operationId?: string;
@@ -33,38 +40,20 @@ export type ModelAttemptToolCall = {
33
40
  transportMeta?: Record<string, unknown> | null;
34
41
  signal?: AbortSignal;
35
42
  };
36
- export declare class AttemptToolCatalogStaleError extends Error {
37
- readonly code = "catalog_stale";
38
- constructor();
39
- }
40
- export declare class AttemptToolNotFoundError extends Error {
41
- readonly code = "tool_not_found";
42
- constructor();
43
- }
44
- export declare class AttemptToolApprovalRequiredError extends Error {
45
- readonly code = "approval_required";
46
- constructor();
47
- }
48
- export declare class AttemptToolCatalogIntegrityError extends Error {
49
- readonly code = "catalog_integrity_failed";
50
- constructor();
51
- }
52
- export declare class AttemptToolCatalogTooLargeError extends Error {
53
- readonly code = "catalog_too_large";
54
- constructor();
55
- }
56
- export declare class AttemptToolInputValidationError extends Error {
57
- readonly code = "invalid_tool_arguments";
58
- constructor();
59
- }
60
- export declare class AttemptToolOutputValidationError extends Error {
61
- readonly code = "invalid_tool_result";
62
- constructor();
63
- }
43
+ export { AttemptToolCatalogStaleError, AttemptToolNotFoundError, AttemptToolApprovalRequiredError, AttemptToolCatalogIntegrityError, AttemptToolCatalogTooLargeError, AttemptToolInputValidationError, AttemptToolOutputValidationError, AttemptToolPathCollisionError, };
64
44
  export declare class CodemodeTransportError extends Error {
65
45
  readonly status: number | null;
66
46
  readonly code = "codemode_transport_error";
67
- constructor(message: string, status?: number | null);
47
+ readonly remoteCode: string | null;
48
+ readonly retryable: boolean | null;
49
+ readonly outcomeUnknown: boolean | null;
50
+ readonly details: Readonly<Record<string, unknown>> | null;
51
+ constructor(message: string, status?: number | null, options?: {
52
+ code?: string;
53
+ retryable?: boolean;
54
+ outcomeUnknown?: boolean;
55
+ details?: Readonly<Record<string, unknown>>;
56
+ });
68
57
  }
69
58
  export declare class CodemodeOperationError extends Error {
70
59
  readonly operation: CodemodeOperationValue;
@@ -82,6 +71,7 @@ export type CodemodeClientOptions = {
82
71
  };
83
72
  export type CodemodeCallOptions = {
84
73
  operationId?: string;
74
+ /** Stops client observation only; it never cancels an already-created server operation. */
85
75
  signal?: AbortSignal;
86
76
  timeoutMs?: number;
87
77
  };
@@ -118,6 +108,7 @@ export declare class CodemodeClient {
118
108
  signal?: AbortSignal;
119
109
  }): Promise<CodemodeTools>;
120
110
  call(identity: AttemptToolIdentity, argumentsValue?: Record<string, unknown>, options?: CodemodeCallOptions): Promise<AttemptToolResultValue>;
111
+ private callResolved;
121
112
  /** Resolve and call one exact generated namespace path without parsing a wire name. */
122
113
  callPath(path: readonly string[], argumentsValue?: Record<string, unknown>, options?: CodemodeCallOptions): Promise<AttemptToolResultValue>;
123
114
  /** Return structured content when the catalog declares it; otherwise retain the full MCP result. */
@@ -127,22 +118,18 @@ export declare class CodemodeClient {
127
118
  private request;
128
119
  }
129
120
  export declare function compileCodemodeTools(catalog: AttemptToolCatalogValue, client: CodemodeClient): CodemodeTools;
130
- type CompiledDefinition = {
131
- entry: AttemptToolCatalogEntryValue;
132
- execute: AttemptToolDefinition["execute"];
133
- validateInput: ValidateFunction<unknown>;
134
- validateOutput: ValidateFunction<unknown> | null;
135
- };
136
121
  export declare class AttemptToolEnvironment {
137
- private readonly authorize;
138
122
  readonly catalog: AttemptToolCatalogValue;
139
- private readonly byIdentity;
140
- private readonly byModelName;
141
- constructor(catalog: AttemptToolCatalogValue, definitions: readonly CompiledDefinition[], authorize: AttemptToolAuthorization | undefined);
123
+ private readonly gateway;
124
+ constructor(catalog: AttemptToolCatalogValue, gateway: ToolGateway);
142
125
  call(input: AttemptToolCallValue, context?: {
143
126
  transportMeta?: Record<string, unknown> | null;
144
127
  signal?: AbortSignal;
145
128
  }): Promise<AttemptToolResultValue>;
129
+ prepareCall(input: AttemptToolCallValue, context?: {
130
+ transportMeta?: Record<string, unknown> | null;
131
+ signal?: AbortSignal;
132
+ }): Promise<PreparedToolGatewayCall>;
146
133
  callModel(input: ModelAttemptToolCall): Promise<AttemptToolResultValue>;
147
134
  }
148
135
  export declare function createAttemptToolEnvironment(input: CreateAttemptToolEnvironmentInput): AttemptToolEnvironment;
@@ -159,3 +146,4 @@ export * from "./interaction.js";
159
146
  export * from "./artifacts.js";
160
147
  export * from "./structured.js";
161
148
  export * from "./declarations.js";
149
+ export * from "./site.js";