@ekairos/openai-reactor 1.22.3 → 1.22.4-beta.development.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 +44 -40
- package/dist/codex.reactor.d.ts +101 -0
- package/dist/codex.reactor.d.ts.map +1 -0
- package/dist/codex.reactor.js +557 -0
- package/dist/codex.reactor.js.map +1 -0
- package/dist/index.d.ts +1 -71
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -148
- package/dist/index.js.map +1 -1
- package/dist/shared.d.ts +24 -0
- package/dist/shared.d.ts.map +1 -0
- package/dist/shared.js +336 -0
- package/dist/shared.js.map +1 -0
- package/package.json +13 -6
package/README.md
CHANGED
|
@@ -1,49 +1,24 @@
|
|
|
1
1
|
# @ekairos/openai-reactor
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Codex reactor for `@ekairos/events`.
|
|
4
|
+
|
|
5
|
+
This package is Codex-only:
|
|
6
|
+
- only `createCodexReactor` is exported,
|
|
7
|
+
- no generic OpenAI model reactor is provided here.
|
|
4
8
|
|
|
5
9
|
## Exports
|
|
6
10
|
|
|
7
|
-
- `createOpenAIReactor(options?)`
|
|
8
|
-
Returns the AI SDK reactor (`streamText`) for Thread. Optional `options`
|
|
9
|
-
let you resolve per-turn `config` and map it into model/max-step settings.
|
|
10
11
|
- `createCodexReactor(options)`
|
|
11
|
-
Codex App Server reactor for direct
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
import { createThread } from "@ekairos/thread";
|
|
17
|
-
import { createOpenAIReactor } from "@ekairos/openai-reactor";
|
|
18
|
-
|
|
19
|
-
const reactor = createOpenAIReactor({
|
|
20
|
-
resolveConfig: async ({ env }) => {
|
|
21
|
-
"use step";
|
|
22
|
-
return {
|
|
23
|
-
model: env.model ?? "openai/gpt-5.2",
|
|
24
|
-
maxModelSteps: 2,
|
|
25
|
-
};
|
|
26
|
-
},
|
|
27
|
-
selectModel: ({ config, baseModel }) => config.model ?? baseModel,
|
|
28
|
-
selectMaxModelSteps: ({ config, baseMaxModelSteps }) =>
|
|
29
|
-
typeof config.maxModelSteps === "number"
|
|
30
|
-
? config.maxModelSteps
|
|
31
|
-
: baseMaxModelSteps,
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
const aiThread = createThread<any>("ai.thread")
|
|
35
|
-
.context((stored) => stored.content ?? {})
|
|
36
|
-
.narrative(() => "General purpose AI thread")
|
|
37
|
-
.actions(() => ({}))
|
|
38
|
-
.reactor(reactor)
|
|
39
|
-
.shouldContinue(() => false)
|
|
40
|
-
.build();
|
|
41
|
-
```
|
|
12
|
+
Codex App Server reactor for direct Context execution (no tool indirection).
|
|
13
|
+
- `mapCodexChunkType(providerChunkType)`
|
|
14
|
+
Maps provider chunk types to canonical Context chunk types.
|
|
15
|
+
- `defaultMapCodexChunk(providerChunk)`
|
|
16
|
+
Default provider-chunk mapper used by the reactor.
|
|
42
17
|
|
|
43
18
|
## Codex Reactor Example
|
|
44
19
|
|
|
45
20
|
```ts
|
|
46
|
-
import {
|
|
21
|
+
import { createContext } from "@ekairos/events";
|
|
47
22
|
import { createCodexReactor } from "@ekairos/openai-reactor";
|
|
48
23
|
|
|
49
24
|
const reactor = createCodexReactor({
|
|
@@ -52,7 +27,7 @@ const reactor = createCodexReactor({
|
|
|
52
27
|
return {
|
|
53
28
|
appServerUrl: env.appServerUrl,
|
|
54
29
|
repoPath: env.repoPath,
|
|
55
|
-
|
|
30
|
+
providerContextId: env.providerContextId,
|
|
56
31
|
mode: "local",
|
|
57
32
|
};
|
|
58
33
|
},
|
|
@@ -60,7 +35,7 @@ const reactor = createCodexReactor({
|
|
|
60
35
|
"use step";
|
|
61
36
|
// call codex app server / stream
|
|
62
37
|
return {
|
|
63
|
-
|
|
38
|
+
providerContextId: config.providerContextId ?? "context_1",
|
|
64
39
|
turnId: "turn_1",
|
|
65
40
|
assistantText: "Done.",
|
|
66
41
|
reasoningText: "",
|
|
@@ -70,15 +45,44 @@ const reactor = createCodexReactor({
|
|
|
70
45
|
},
|
|
71
46
|
});
|
|
72
47
|
|
|
73
|
-
const
|
|
48
|
+
const codingContext = createContext<any>("code.agent")
|
|
74
49
|
.context((stored) => stored.content ?? {})
|
|
75
|
-
.narrative(() => "Ekairos coding
|
|
50
|
+
.narrative(() => "Ekairos coding context")
|
|
76
51
|
.actions(() => ({}))
|
|
77
52
|
.reactor(reactor)
|
|
78
53
|
.shouldContinue(() => false)
|
|
79
54
|
.build();
|
|
80
55
|
```
|
|
81
56
|
|
|
57
|
+
## Provider stream -> Context mapping
|
|
58
|
+
|
|
59
|
+
For each provider chunk you emit via `emitChunk(providerChunk)`, the reactor writes:
|
|
60
|
+
|
|
61
|
+
- SSE chunk event: `data-chunk.emitted` with canonical `chunkType` (`chunk.text_delta`, `chunk.action_input_available`, etc.)
|
|
62
|
+
- `codex-event` part metadata on the persisted output item:
|
|
63
|
+
- `streamTrace.totalChunks`
|
|
64
|
+
- `streamTrace.chunkTypes`
|
|
65
|
+
- `streamTrace.providerChunkTypes`
|
|
66
|
+
- `streamTrace.chunks[]` (configurable)
|
|
67
|
+
|
|
68
|
+
Default behavior persists stream trace summary and mapped chunks in the final `codex-event`.
|
|
69
|
+
|
|
70
|
+
Config options:
|
|
71
|
+
|
|
72
|
+
- `includeStreamTraceInOutput` (default: `true`)
|
|
73
|
+
- `includeRawProviderChunksInOutput` (default: `false`)
|
|
74
|
+
- `maxPersistedStreamChunks` (default: `300`)
|
|
75
|
+
- `onMappedChunk(chunk, params)` hook for custom telemetry pipelines
|
|
76
|
+
|
|
82
77
|
## Workflow Compatibility
|
|
83
78
|
|
|
84
79
|
`resolveConfig` and `executeTurn` should be implemented as workflow-safe step functions when they perform I/O.
|
|
80
|
+
|
|
81
|
+
## AI SDK generic reactor
|
|
82
|
+
|
|
83
|
+
`createAiSdkReactor(...)` is provider-agnostic and lives in `@ekairos/events`.
|
|
84
|
+
|
|
85
|
+
## TODO
|
|
86
|
+
|
|
87
|
+
- Continuity across machines should be validated end-to-end with persisted session state.
|
|
88
|
+
- Current continuity assumption in local tests is: keep the same `contextId` and reuse the same provider `providerContextId` between turns.
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { type ContextSkillPackage, type ContextItem, type ContextReactor, type ContextReactorParams, type ContextStreamChunkType } from "@ekairos/events";
|
|
2
|
+
import type { ContextEnvironment } from "@ekairos/events/runtime";
|
|
3
|
+
import { type AnyRecord } from "./shared.js";
|
|
4
|
+
export type CodexConfig = {
|
|
5
|
+
appServerUrl: string;
|
|
6
|
+
repoPath: string;
|
|
7
|
+
providerContextId?: string;
|
|
8
|
+
mode?: "local" | "remote" | "sandbox";
|
|
9
|
+
model?: string;
|
|
10
|
+
approvalPolicy?: string;
|
|
11
|
+
sandboxPolicy?: Record<string, unknown>;
|
|
12
|
+
};
|
|
13
|
+
export type CodexTurnResult = {
|
|
14
|
+
providerContextId: string;
|
|
15
|
+
turnId: string;
|
|
16
|
+
assistantText: string;
|
|
17
|
+
reasoningText?: string;
|
|
18
|
+
diff?: string;
|
|
19
|
+
toolParts?: unknown[];
|
|
20
|
+
metadata?: Record<string, unknown>;
|
|
21
|
+
usage?: Record<string, unknown>;
|
|
22
|
+
};
|
|
23
|
+
export type CodexExecuteTurnArgs<Context, Config extends CodexConfig = CodexConfig, Env extends ContextEnvironment = ContextEnvironment> = {
|
|
24
|
+
env: Env;
|
|
25
|
+
context: AnyRecord;
|
|
26
|
+
triggerEvent: ContextItem;
|
|
27
|
+
contextId: string;
|
|
28
|
+
eventId: string;
|
|
29
|
+
executionId: string;
|
|
30
|
+
stepId: string;
|
|
31
|
+
iteration: number;
|
|
32
|
+
instruction: string;
|
|
33
|
+
config: Config;
|
|
34
|
+
skills: ContextSkillPackage[];
|
|
35
|
+
writable?: WritableStream<unknown>;
|
|
36
|
+
silent: boolean;
|
|
37
|
+
emitChunk: (providerChunk: unknown) => Promise<void>;
|
|
38
|
+
};
|
|
39
|
+
export type CodexChunkMappingResult = {
|
|
40
|
+
chunkType: ContextStreamChunkType;
|
|
41
|
+
providerChunkType?: string;
|
|
42
|
+
actionRef?: string;
|
|
43
|
+
data?: unknown;
|
|
44
|
+
raw?: unknown;
|
|
45
|
+
skip?: boolean;
|
|
46
|
+
};
|
|
47
|
+
export type CodexMappedChunk = {
|
|
48
|
+
at: string;
|
|
49
|
+
sequence: number;
|
|
50
|
+
chunkType: ContextStreamChunkType;
|
|
51
|
+
providerChunkType?: string;
|
|
52
|
+
actionRef?: string;
|
|
53
|
+
data?: unknown;
|
|
54
|
+
raw?: unknown;
|
|
55
|
+
};
|
|
56
|
+
export type CodexStreamTrace = {
|
|
57
|
+
totalChunks: number;
|
|
58
|
+
chunkTypes: Record<string, number>;
|
|
59
|
+
providerChunkTypes: Record<string, number>;
|
|
60
|
+
chunks?: CodexMappedChunk[];
|
|
61
|
+
};
|
|
62
|
+
export type CreateCodexReactorOptions<Context, Config extends CodexConfig = CodexConfig, Env extends ContextEnvironment = ContextEnvironment> = {
|
|
63
|
+
toolName?: string;
|
|
64
|
+
includeReasoningPart?: boolean;
|
|
65
|
+
buildInstruction?: (params: {
|
|
66
|
+
env: Env;
|
|
67
|
+
context: AnyRecord;
|
|
68
|
+
triggerEvent: ContextItem;
|
|
69
|
+
}) => string | Promise<string>;
|
|
70
|
+
resolveConfig: (params: {
|
|
71
|
+
env: Env;
|
|
72
|
+
context: AnyRecord;
|
|
73
|
+
triggerEvent: ContextItem;
|
|
74
|
+
contextId: string;
|
|
75
|
+
eventId: string;
|
|
76
|
+
executionId: string;
|
|
77
|
+
stepId: string;
|
|
78
|
+
iteration: number;
|
|
79
|
+
}) => Promise<Config>;
|
|
80
|
+
executeTurn: (args: CodexExecuteTurnArgs<Context, Config, Env>) => Promise<CodexTurnResult>;
|
|
81
|
+
mapChunk?: (providerChunk: unknown) => CodexChunkMappingResult | null;
|
|
82
|
+
includeStreamTraceInOutput?: boolean;
|
|
83
|
+
includeRawProviderChunksInOutput?: boolean;
|
|
84
|
+
maxPersistedStreamChunks?: number;
|
|
85
|
+
onMappedChunk?: (chunk: CodexMappedChunk, params: ContextReactorParams<Context, Env>) => Promise<void> | void;
|
|
86
|
+
};
|
|
87
|
+
export declare function mapCodexChunkType(providerChunkType: string): ContextStreamChunkType;
|
|
88
|
+
export declare function mapCodexAppServerNotification(providerChunk: unknown): CodexChunkMappingResult | null;
|
|
89
|
+
export declare function defaultMapCodexChunk(providerChunk: unknown): CodexChunkMappingResult;
|
|
90
|
+
/**
|
|
91
|
+
* Codex App Server reactor for @ekairos/events.
|
|
92
|
+
*
|
|
93
|
+
* This maps one Context loop iteration to one Codex turn and returns a persisted
|
|
94
|
+
* assistant event compatible with the Context engine.
|
|
95
|
+
*
|
|
96
|
+
* Workflow compatibility:
|
|
97
|
+
* - `resolveConfig` and `executeTurn` should be implemented with `"use step"`
|
|
98
|
+
* wrappers when they perform I/O.
|
|
99
|
+
*/
|
|
100
|
+
export declare function createCodexReactor<Context, Config extends CodexConfig = CodexConfig, Env extends ContextEnvironment = ContextEnvironment>(options: CreateCodexReactorOptions<Context, Config, Env>): ContextReactor<Context, Env>;
|
|
101
|
+
//# sourceMappingURL=codex.reactor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex.reactor.d.ts","sourceRoot":"","sources":["../src/codex.reactor.ts"],"names":[],"mappings":"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"}
|