@execlave/sdk 1.0.2 → 1.1.2

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 (47) hide show
  1. package/README.md +65 -48
  2. package/dist/client.d.ts.map +1 -1
  3. package/dist/client.js +5 -1
  4. package/dist/client.js.map +1 -1
  5. package/dist/errors.d.ts +17 -0
  6. package/dist/errors.d.ts.map +1 -1
  7. package/dist/errors.js +24 -1
  8. package/dist/errors.js.map +1 -1
  9. package/dist/index.d.ts +1 -1
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +2 -1
  12. package/dist/index.js.map +1 -1
  13. package/dist/instrumentation/events.d.ts +35 -0
  14. package/dist/instrumentation/events.d.ts.map +1 -0
  15. package/dist/instrumentation/events.js +137 -0
  16. package/dist/instrumentation/events.js.map +1 -0
  17. package/dist/instrumentation/index.d.ts +11 -0
  18. package/dist/instrumentation/index.d.ts.map +1 -0
  19. package/dist/instrumentation/index.js +28 -0
  20. package/dist/instrumentation/index.js.map +1 -0
  21. package/dist/instrumentation/spans.d.ts +72 -0
  22. package/dist/instrumentation/spans.d.ts.map +1 -0
  23. package/dist/instrumentation/spans.js +136 -0
  24. package/dist/instrumentation/spans.js.map +1 -0
  25. package/dist/integrations/crewai.d.ts +44 -0
  26. package/dist/integrations/crewai.d.ts.map +1 -0
  27. package/dist/integrations/crewai.js +224 -0
  28. package/dist/integrations/crewai.js.map +1 -0
  29. package/dist/integrations/index.d.ts +16 -0
  30. package/dist/integrations/index.d.ts.map +1 -0
  31. package/dist/integrations/index.js +19 -0
  32. package/dist/integrations/index.js.map +1 -0
  33. package/dist/integrations/langchain.d.ts +90 -0
  34. package/dist/integrations/langchain.d.ts.map +1 -0
  35. package/dist/integrations/langchain.js +240 -0
  36. package/dist/integrations/langchain.js.map +1 -0
  37. package/dist/integrations/openai-agents.d.ts +60 -0
  38. package/dist/integrations/openai-agents.d.ts.map +1 -0
  39. package/dist/integrations/openai-agents.js +247 -0
  40. package/dist/integrations/openai-agents.js.map +1 -0
  41. package/dist/trace.d.ts +21 -2
  42. package/dist/trace.d.ts.map +1 -1
  43. package/dist/trace.js +34 -4
  44. package/dist/trace.js.map +1 -1
  45. package/dist/types.d.ts +10 -0
  46. package/dist/types.d.ts.map +1 -1
  47. package/package.json +38 -5
@@ -0,0 +1,137 @@
1
+ "use strict";
2
+ /**
3
+ * High-level event helpers used by framework adapters (mirror of the
4
+ * Python events module).
5
+ *
6
+ * Helpers run `exe.enforcePolicy(...)` pre-execution and open a span
7
+ * under the current span stack. Policy-block errors re-raise;
8
+ * transient enforcement errors are swallowed with a console.warn.
9
+ */
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.recordLlmCall = recordLlmCall;
12
+ exports.recordToolCall = recordToolCall;
13
+ exports.recordAgentAction = recordAgentAction;
14
+ exports.recordRetrieval = recordRetrieval;
15
+ const errors_1 = require("../errors");
16
+ const spans_1 = require("./spans");
17
+ function isEnforcementError(err) {
18
+ return (err instanceof errors_1.PolicyBlockedError ||
19
+ err instanceof errors_1.PolicyDeniedError ||
20
+ err instanceof errors_1.ApprovalTimeoutError ||
21
+ err instanceof errors_1.EnforcementUnavailableError ||
22
+ err instanceof errors_1.AgentPausedError);
23
+ }
24
+ async function maybeEnforce(exe, opts) {
25
+ if (!opts.agentId || opts.input == null)
26
+ return null;
27
+ try {
28
+ return await exe.enforcePolicy({
29
+ agentId: opts.agentId,
30
+ input: opts.input,
31
+ tools: opts.tools,
32
+ metadata: opts.metadata,
33
+ estimatedCost: opts.estimatedCost,
34
+ });
35
+ }
36
+ catch (err) {
37
+ if (isEnforcementError(err))
38
+ throw err;
39
+ // eslint-disable-next-line no-console
40
+ console.warn('[execlave] enforcePolicy failed (non-fatal):', err);
41
+ return null;
42
+ }
43
+ }
44
+ function summariseDecision(decision) {
45
+ if (!decision || typeof decision !== 'object')
46
+ return {};
47
+ const out = {};
48
+ for (const k of ['allowed', 'mode', 'source', 'warnings', 'requiresApproval']) {
49
+ if (k in decision)
50
+ out[k] = decision[k];
51
+ }
52
+ return out;
53
+ }
54
+ async function recordLlmCall(exe, opts, fn) {
55
+ const decision = await maybeEnforce(exe, opts);
56
+ const tree = (0, spans_1.getSpanTree)(exe);
57
+ const span = tree.start({
58
+ kind: spans_1.SPAN_KIND_LLM,
59
+ name: opts.model ?? 'llm',
60
+ agentId: opts.agentId,
61
+ });
62
+ if (opts.input != null)
63
+ span.setInput(opts.input);
64
+ if (opts.model)
65
+ span.setModel(opts.model);
66
+ if (decision)
67
+ span.addMetadata({ enforcement: summariseDecision(decision) });
68
+ try {
69
+ const result = await fn(span);
70
+ span.finish('success');
71
+ return result;
72
+ }
73
+ catch (err) {
74
+ const e = err;
75
+ span.finish('error', e?.message, e?.name);
76
+ throw err;
77
+ }
78
+ }
79
+ async function recordToolCall(exe, opts, fn) {
80
+ const decision = await maybeEnforce(exe, {
81
+ agentId: opts.agentId,
82
+ input: opts.input ?? `tool:${opts.toolName}`,
83
+ tools: [opts.toolName],
84
+ metadata: { ...(opts.metadata ?? {}), toolName: opts.toolName },
85
+ });
86
+ const tree = (0, spans_1.getSpanTree)(exe);
87
+ const span = tree.start({
88
+ kind: spans_1.SPAN_KIND_TOOL,
89
+ name: opts.toolName,
90
+ agentId: opts.agentId,
91
+ });
92
+ if (opts.input != null)
93
+ span.setInput(opts.input);
94
+ span.addMetadata({ toolName: opts.toolName });
95
+ if (decision)
96
+ span.addMetadata({ enforcement: summariseDecision(decision) });
97
+ try {
98
+ const result = await fn(span);
99
+ span.finish('success');
100
+ return result;
101
+ }
102
+ catch (err) {
103
+ const e = err;
104
+ span.finish('error', e?.message, e?.name);
105
+ throw err;
106
+ }
107
+ }
108
+ function recordAgentAction(exe, opts) {
109
+ const tree = (0, spans_1.getSpanTree)(exe);
110
+ return tree.start({
111
+ kind: spans_1.SPAN_KIND_AGENT,
112
+ name: opts.action,
113
+ agentId: opts.agentId,
114
+ metadata: opts.metadata,
115
+ });
116
+ }
117
+ async function recordRetrieval(exe, opts, fn) {
118
+ const tree = (0, spans_1.getSpanTree)(exe);
119
+ const span = tree.start({
120
+ kind: spans_1.SPAN_KIND_RETRIEVER,
121
+ name: opts.retrieverName ?? 'retriever',
122
+ agentId: opts.agentId,
123
+ metadata: opts.metadata,
124
+ });
125
+ span.setInput(opts.query);
126
+ try {
127
+ const result = await fn(span);
128
+ span.finish('success');
129
+ return result;
130
+ }
131
+ catch (err) {
132
+ const e = err;
133
+ span.finish('error', e?.message, e?.name);
134
+ throw err;
135
+ }
136
+ }
137
+ //# sourceMappingURL=events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/instrumentation/events.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Shared internal instrumentation layer — JS mirror of
3
+ * `sdk-python/execlave/instrumentation/`.
4
+ *
5
+ * Provides nested span primitives + event helpers consumed by
6
+ * framework adapters (LangChain, etc.). Zero runtime deps beyond the
7
+ * base SDK.
8
+ */
9
+ export { Span, SpanTree, getSpanTree, SPAN_KIND_AGENT, SPAN_KIND_CHAIN, SPAN_KIND_LLM, SPAN_KIND_TOOL, SPAN_KIND_RETRIEVER, SPAN_KIND_GUARDRAIL, SPAN_KIND_HANDOFF, type SpanKind, } from './spans';
10
+ export { recordLlmCall, recordToolCall, recordAgentAction, recordRetrieval, } from './events';
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/instrumentation/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EACL,IAAI,EACJ,QAAQ,EACR,WAAW,EACX,eAAe,EACf,eAAe,EACf,aAAa,EACb,cAAc,EACd,mBAAmB,EACnB,mBAAmB,EACnB,iBAAiB,EACjB,KAAK,QAAQ,GACd,MAAM,SAAS,CAAC;AACjB,OAAO,EACL,aAAa,EACb,cAAc,EACd,iBAAiB,EACjB,eAAe,GAChB,MAAM,UAAU,CAAC"}
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ /**
3
+ * Shared internal instrumentation layer — JS mirror of
4
+ * `sdk-python/execlave/instrumentation/`.
5
+ *
6
+ * Provides nested span primitives + event helpers consumed by
7
+ * framework adapters (LangChain, etc.). Zero runtime deps beyond the
8
+ * base SDK.
9
+ */
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.recordRetrieval = exports.recordAgentAction = exports.recordToolCall = exports.recordLlmCall = exports.SPAN_KIND_HANDOFF = exports.SPAN_KIND_GUARDRAIL = exports.SPAN_KIND_RETRIEVER = exports.SPAN_KIND_TOOL = exports.SPAN_KIND_LLM = exports.SPAN_KIND_CHAIN = exports.SPAN_KIND_AGENT = exports.getSpanTree = exports.SpanTree = exports.Span = void 0;
12
+ var spans_1 = require("./spans");
13
+ Object.defineProperty(exports, "Span", { enumerable: true, get: function () { return spans_1.Span; } });
14
+ Object.defineProperty(exports, "SpanTree", { enumerable: true, get: function () { return spans_1.SpanTree; } });
15
+ Object.defineProperty(exports, "getSpanTree", { enumerable: true, get: function () { return spans_1.getSpanTree; } });
16
+ Object.defineProperty(exports, "SPAN_KIND_AGENT", { enumerable: true, get: function () { return spans_1.SPAN_KIND_AGENT; } });
17
+ Object.defineProperty(exports, "SPAN_KIND_CHAIN", { enumerable: true, get: function () { return spans_1.SPAN_KIND_CHAIN; } });
18
+ Object.defineProperty(exports, "SPAN_KIND_LLM", { enumerable: true, get: function () { return spans_1.SPAN_KIND_LLM; } });
19
+ Object.defineProperty(exports, "SPAN_KIND_TOOL", { enumerable: true, get: function () { return spans_1.SPAN_KIND_TOOL; } });
20
+ Object.defineProperty(exports, "SPAN_KIND_RETRIEVER", { enumerable: true, get: function () { return spans_1.SPAN_KIND_RETRIEVER; } });
21
+ Object.defineProperty(exports, "SPAN_KIND_GUARDRAIL", { enumerable: true, get: function () { return spans_1.SPAN_KIND_GUARDRAIL; } });
22
+ Object.defineProperty(exports, "SPAN_KIND_HANDOFF", { enumerable: true, get: function () { return spans_1.SPAN_KIND_HANDOFF; } });
23
+ var events_1 = require("./events");
24
+ Object.defineProperty(exports, "recordLlmCall", { enumerable: true, get: function () { return events_1.recordLlmCall; } });
25
+ Object.defineProperty(exports, "recordToolCall", { enumerable: true, get: function () { return events_1.recordToolCall; } });
26
+ Object.defineProperty(exports, "recordAgentAction", { enumerable: true, get: function () { return events_1.recordAgentAction; } });
27
+ Object.defineProperty(exports, "recordRetrieval", { enumerable: true, get: function () { return events_1.recordRetrieval; } });
28
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/instrumentation/index.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;;AAEH,iCAYiB;AAXf,6FAAA,IAAI,OAAA;AACJ,iGAAA,QAAQ,OAAA;AACR,oGAAA,WAAW,OAAA;AACX,wGAAA,eAAe,OAAA;AACf,wGAAA,eAAe,OAAA;AACf,sGAAA,aAAa,OAAA;AACb,uGAAA,cAAc,OAAA;AACd,4GAAA,mBAAmB,OAAA;AACnB,4GAAA,mBAAmB,OAAA;AACnB,0GAAA,iBAAiB,OAAA;AAGnB,mCAKkB;AAJhB,uGAAA,aAAa,OAAA;AACb,wGAAA,cAAc,OAAA;AACd,2GAAA,iBAAiB,OAAA;AACjB,yGAAA,eAAe,OAAA"}
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Nested span primitives. Each `Span` wraps the SDK's `Trace` and
3
+ * carries parent/child identity through the trace metadata so the
4
+ * backend can reconstruct the execution tree.
5
+ *
6
+ * Concurrency model: Node.js is single-threaded, but async tasks can
7
+ * interleave. We expose `withSpan(span, fn)` so async framework
8
+ * adapters can scope the "current span" to a specific async operation
9
+ * without relying on AsyncLocalStorage (keeps footprint zero-dep).
10
+ * The default stack is process-wide; framework adapters can pass
11
+ * `parent` explicitly to avoid relying on the implicit stack.
12
+ */
13
+ import { Trace } from '../trace';
14
+ import type { Execlave } from '../client';
15
+ export declare const SPAN_KIND_AGENT = "agent";
16
+ export declare const SPAN_KIND_CHAIN = "chain";
17
+ export declare const SPAN_KIND_LLM = "llm";
18
+ export declare const SPAN_KIND_TOOL = "tool";
19
+ export declare const SPAN_KIND_RETRIEVER = "retriever";
20
+ export declare const SPAN_KIND_GUARDRAIL = "guardrail";
21
+ export declare const SPAN_KIND_HANDOFF = "handoff";
22
+ export type SpanKind = typeof SPAN_KIND_AGENT | typeof SPAN_KIND_CHAIN | typeof SPAN_KIND_LLM | typeof SPAN_KIND_TOOL | typeof SPAN_KIND_RETRIEVER | typeof SPAN_KIND_GUARDRAIL | typeof SPAN_KIND_HANDOFF;
23
+ export interface StartSpanOptions {
24
+ kind: SpanKind;
25
+ name: string;
26
+ parent?: Span | null;
27
+ agentId?: string;
28
+ sessionId?: string;
29
+ userId?: string;
30
+ metadata?: Record<string, unknown>;
31
+ }
32
+ export declare class Span {
33
+ readonly spanId: string;
34
+ readonly parentSpanId: string | null;
35
+ readonly kind: SpanKind;
36
+ readonly name: string;
37
+ private _trace;
38
+ private _tree;
39
+ private _finished;
40
+ constructor(trace: Trace, opts: {
41
+ spanId: string;
42
+ parentSpanId: string | null;
43
+ kind: SpanKind;
44
+ name: string;
45
+ tree: SpanTree;
46
+ });
47
+ /** Internal: exposed for nested spans to inherit trace id. */
48
+ get _innerTrace(): Trace;
49
+ /** Trace id that this span's metadata is attached to. */
50
+ get traceId(): string;
51
+ setInput(value: unknown): this;
52
+ setOutput(value: unknown): this;
53
+ setModel(model: string): this;
54
+ setTokens(prompt: number, completion: number): this;
55
+ setCost(costUsd: number): this;
56
+ addMetadata(meta: Record<string, unknown>): this;
57
+ child(opts: {
58
+ kind: SpanKind;
59
+ name: string;
60
+ }): Span;
61
+ finish(status?: 'success' | 'error' | 'timeout', errorMessage?: string, errorType?: string): void;
62
+ }
63
+ export declare class SpanTree {
64
+ private _exe;
65
+ private _stack;
66
+ constructor(_exe: Execlave);
67
+ current(): Span | null;
68
+ start(opts: StartSpanOptions): Span;
69
+ _pop(span: Span): void;
70
+ }
71
+ export declare function getSpanTree(exe: Execlave): SpanTree;
72
+ //# sourceMappingURL=spans.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spans.d.ts","sourceRoot":"","sources":["../../src/instrumentation/spans.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,136 @@
1
+ "use strict";
2
+ /**
3
+ * Nested span primitives. Each `Span` wraps the SDK's `Trace` and
4
+ * carries parent/child identity through the trace metadata so the
5
+ * backend can reconstruct the execution tree.
6
+ *
7
+ * Concurrency model: Node.js is single-threaded, but async tasks can
8
+ * interleave. We expose `withSpan(span, fn)` so async framework
9
+ * adapters can scope the "current span" to a specific async operation
10
+ * without relying on AsyncLocalStorage (keeps footprint zero-dep).
11
+ * The default stack is process-wide; framework adapters can pass
12
+ * `parent` explicitly to avoid relying on the implicit stack.
13
+ */
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.SpanTree = exports.Span = exports.SPAN_KIND_HANDOFF = exports.SPAN_KIND_GUARDRAIL = exports.SPAN_KIND_RETRIEVER = exports.SPAN_KIND_TOOL = exports.SPAN_KIND_LLM = exports.SPAN_KIND_CHAIN = exports.SPAN_KIND_AGENT = void 0;
16
+ exports.getSpanTree = getSpanTree;
17
+ const crypto_1 = require("crypto");
18
+ exports.SPAN_KIND_AGENT = 'agent';
19
+ exports.SPAN_KIND_CHAIN = 'chain';
20
+ exports.SPAN_KIND_LLM = 'llm';
21
+ exports.SPAN_KIND_TOOL = 'tool';
22
+ exports.SPAN_KIND_RETRIEVER = 'retriever';
23
+ exports.SPAN_KIND_GUARDRAIL = 'guardrail';
24
+ exports.SPAN_KIND_HANDOFF = 'handoff';
25
+ class Span {
26
+ constructor(trace, opts) {
27
+ this._finished = false;
28
+ this._trace = trace;
29
+ this.spanId = opts.spanId;
30
+ this.parentSpanId = opts.parentSpanId;
31
+ this.kind = opts.kind;
32
+ this.name = opts.name;
33
+ this._tree = opts.tree;
34
+ trace.addMetadata({
35
+ spanId: this.spanId,
36
+ parentSpanId: this.parentSpanId,
37
+ spanKind: this.kind,
38
+ spanName: this.name,
39
+ });
40
+ }
41
+ /** Internal: exposed for nested spans to inherit trace id. */
42
+ get _innerTrace() {
43
+ return this._trace;
44
+ }
45
+ /** Trace id that this span's metadata is attached to. */
46
+ get traceId() {
47
+ return this._trace.traceId;
48
+ }
49
+ setInput(value) {
50
+ this._trace.setInput(value);
51
+ return this;
52
+ }
53
+ setOutput(value) {
54
+ this._trace.setOutput(value);
55
+ return this;
56
+ }
57
+ setModel(model) {
58
+ this._trace.setModel(model);
59
+ return this;
60
+ }
61
+ setTokens(prompt, completion) {
62
+ this._trace.setTokens(prompt, completion);
63
+ return this;
64
+ }
65
+ setCost(costUsd) {
66
+ this._trace.setCost(costUsd);
67
+ return this;
68
+ }
69
+ addMetadata(meta) {
70
+ this._trace.addMetadata(meta);
71
+ return this;
72
+ }
73
+ child(opts) {
74
+ return this._tree.start({ ...opts, parent: this });
75
+ }
76
+ finish(status = 'success', errorMessage, errorType) {
77
+ if (this._finished)
78
+ return;
79
+ this._finished = true;
80
+ this._tree._pop(this);
81
+ try {
82
+ this._trace.finish(status, errorMessage, errorType);
83
+ }
84
+ catch {
85
+ // transport/buffer errors are never fatal for the host app.
86
+ }
87
+ }
88
+ }
89
+ exports.Span = Span;
90
+ class SpanTree {
91
+ constructor(_exe) {
92
+ this._exe = _exe;
93
+ this._stack = [];
94
+ }
95
+ current() {
96
+ return this._stack.length > 0 ? this._stack[this._stack.length - 1] : null;
97
+ }
98
+ start(opts) {
99
+ const parent = opts.parent ?? this.current();
100
+ const parentId = parent ? parent.spanId : null;
101
+ const inherited = parent ? parent._innerTrace : null;
102
+ const trace = this._exe.startTrace({
103
+ traceId: inherited ? inherited.traceId : undefined,
104
+ agentId: opts.agentId ?? inherited?.agentId,
105
+ sessionId: opts.sessionId ?? inherited?.sessionId,
106
+ userId: opts.userId ?? inherited?.userId,
107
+ metadata: opts.metadata,
108
+ });
109
+ const spanId = `sp_${(0, crypto_1.randomBytes)(8).toString('hex')}`;
110
+ const span = new Span(trace, {
111
+ spanId,
112
+ parentSpanId: parentId,
113
+ kind: opts.kind,
114
+ name: opts.name,
115
+ tree: this,
116
+ });
117
+ this._stack.push(span);
118
+ return span;
119
+ }
120
+ _pop(span) {
121
+ const idx = this._stack.lastIndexOf(span);
122
+ if (idx >= 0)
123
+ this._stack.splice(idx, 1);
124
+ }
125
+ }
126
+ exports.SpanTree = SpanTree;
127
+ const _treeCache = new WeakMap();
128
+ function getSpanTree(exe) {
129
+ let tree = _treeCache.get(exe);
130
+ if (!tree) {
131
+ tree = new SpanTree(exe);
132
+ _treeCache.set(exe, tree);
133
+ }
134
+ return tree;
135
+ }
136
+ //# sourceMappingURL=spans.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spans.js","sourceRoot":"","sources":["../../src/instrumentation/spans.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * CrewAI auto-instrumentation.
3
+ *
4
+ * Usage:
5
+ *
6
+ * ```ts
7
+ * import { Crew } from 'crewai';
8
+ * import { Execlave } from '@execlave/sdk';
9
+ * import { instrumentCrew } from '@execlave/sdk/integrations/crewai';
10
+ *
11
+ * const exe = new Execlave({ apiKey: '...' });
12
+ * const crew = new Crew({ agents: [...], tasks: [...] });
13
+ * instrumentCrew(crew, exe, { agentId: 'my-crew' });
14
+ * await crew.kickoff();
15
+ * ```
16
+ *
17
+ * Implementation: CrewAI exposes `stepCallback` and `taskCallback` hooks
18
+ * on `Agent` and `Crew` objects. We chain our callbacks in front of any
19
+ * existing user callbacks so attaching the instrumentation never
20
+ * overrides user-supplied hooks.
21
+ *
22
+ * Idempotent — `_execlaveInstrumented` marker prevents double-wrapping.
23
+ *
24
+ * Note: CrewAI's first-class JS implementation is still emerging; this
25
+ * helper duck-types the callback shape so it works with both the
26
+ * official package and community ports. No compile-time dependency.
27
+ */
28
+ import type { Execlave } from '../client';
29
+ export interface InstrumentCrewOptions {
30
+ /** Agent id registered with Execlave. Required for enforcement. */
31
+ agentId: string;
32
+ /** Run `enforcePolicy` on tool steps. Default true. */
33
+ enforce?: boolean;
34
+ sessionId?: string;
35
+ userId?: string;
36
+ }
37
+ /**
38
+ * Attach Execlave instrumentation to a CrewAI `Crew` instance.
39
+ *
40
+ * Idempotent: calling twice on the same crew is a no-op. Returns the
41
+ * same crew for fluent chaining.
42
+ */
43
+ export declare function instrumentCrew<T>(crew: T, exe: Execlave, opts: InstrumentCrewOptions): T;
44
+ //# sourceMappingURL=crewai.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crewai.d.ts","sourceRoot":"","sources":["../../src/integrations/crewai.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AA2B1C,MAAM,WAAW,qBAAqB;IACpC,mEAAmE;IACnE,OAAO,EAAE,MAAM,CAAC;IAChB,uDAAuD;IACvD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,qBAAqB,GAAG,CAAC,CAqDxF"}