Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions cypilot/.core/skills/connector/workflows/create.md
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,8 @@ If `validate-strict` fails, do NOT proceed. Fix per-path errors first — the Bu

If `validate-strict` passes but `validate` fails, there is a runtime problem — usually a bad Jinja expression, a template reference to an undefined config key, or a `$ref` pointing at a path that does not exist.

Both validators run inside `airbyte/source-declarative-manifest` pinned (in `source.sh` / `Dockerfile`) to the CDK version bundled with the deployed Airbyte platform — see `src/ingestion/tools/declarative-connector/README.md` §"Validator image pin". Never override the image to `:latest`: its strict schema drifts ahead of the deployed Builder UI and produces false failures.

### 5.3 Check credentials against API

```bash
Expand Down
90 changes: 60 additions & 30 deletions src/ingestion/connectors/ai/claude-admin/connector.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,17 @@ definitions:
tenant_id_injection:
type: AddFields
fields:
- path: [tenant_id]
- type: AddedFieldDefinition
path: [tenant_id]
value: "{{ config['insight_tenant_id'] }}"
- path: [insight_source_id]
- type: AddedFieldDefinition
path: [insight_source_id]
value: "{{ config.get('insight_source_id', '') }}"
- path: [collected_at]
- type: AddedFieldDefinition
path: [collected_at]
value: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}"
- path: [data_source]
- type: AddedFieldDefinition
path: [data_source]
value: insight_claude_admin

cursor_paginator:
Expand Down Expand Up @@ -225,17 +229,23 @@ streams:
- $ref: "#/definitions/tenant_id_injection"
- type: AddFields
fields:
- path: [date]
- type: AddedFieldDefinition
path: [date]
value: "{{ stream_interval['start_time'][:10] }}"
- path: [cache_read_tokens]
- type: AddedFieldDefinition
path: [cache_read_tokens]
value: "{{ record.get('cache_read_input_tokens', 0) }}"
- path: [cache_creation_5m_tokens]
- type: AddedFieldDefinition
path: [cache_creation_5m_tokens]
value: "{{ record.get('cache_creation', {}).get('ephemeral_5m_input_tokens', 0) }}"
- path: [cache_creation_1h_tokens]
- type: AddedFieldDefinition
path: [cache_creation_1h_tokens]
value: "{{ record.get('cache_creation', {}).get('ephemeral_1h_input_tokens', 0) }}"
- path: [web_search_requests]
- type: AddedFieldDefinition
path: [web_search_requests]
value: "{{ record.get('server_tool_use', {}).get('web_search_requests', 0) }}"
- path: [unique]
- type: AddedFieldDefinition
path: [unique]
value: "{{ stream_interval['start_time'][:10] }}|{{ record.get('model') or '' }}|{{ record.get('api_key_id') or '' }}|{{ record.get('workspace_id') or '' }}|{{ record.get('service_tier') or '' }}|{{ record.get('context_window') or '' }}"
incremental_sync:
type: DatetimeBasedCursor
Expand Down Expand Up @@ -349,9 +359,11 @@ streams:
- $ref: "#/definitions/tenant_id_injection"
- type: AddFields
fields:
- path: [date]
- type: AddedFieldDefinition
path: [date]
value: "{{ stream_interval['start_time'][:10] }}"
- path: [unique]
- type: AddedFieldDefinition
path: [unique]
value: "{{ stream_interval['start_time'][:10] }}|{{ record.get('workspace_id') or '' }}|{{ record.get('description') or '' }}"
incremental_sync:
type: DatetimeBasedCursor
Expand Down Expand Up @@ -469,29 +481,41 @@ streams:
- $ref: "#/definitions/tenant_id_injection"
- type: AddFields
fields:
- path: [date]
- type: AddedFieldDefinition
path: [date]
value: "{{ record.get('date', '')[:10] }}"
- path: [actor_type]
- type: AddedFieldDefinition
path: [actor_type]
value: "{{ record.get('actor', {}).get('type') or '' }}"
- path: [actor_identifier]
- type: AddedFieldDefinition
path: [actor_identifier]
value: "{{ record.get('actor', {}).get('api_key_name') or record.get('actor', {}).get('email') or '' }}"
- path: [session_count]
- type: AddedFieldDefinition
path: [session_count]
value: "{{ record.get('core_metrics', {}).get('num_sessions', 0) }}"
- path: [lines_added]
- type: AddedFieldDefinition
path: [lines_added]
value: "{{ record.get('core_metrics', {}).get('lines_of_code', {}).get('added', 0) }}"
- path: [lines_removed]
- type: AddedFieldDefinition
path: [lines_removed]
value: "{{ record.get('core_metrics', {}).get('lines_of_code', {}).get('removed', 0) }}"
- path: [tool_use_accepted]
- type: AddedFieldDefinition
path: [tool_use_accepted]
value: "{{ (record.get('tool_actions', {}).get('edit_tool', {}).get('accepted', 0) or 0) + (record.get('tool_actions', {}).get('write_tool', {}).get('accepted', 0) or 0) + (record.get('tool_actions', {}).get('multi_edit_tool', {}).get('accepted', 0) or 0) + (record.get('tool_actions', {}).get('notebook_edit_tool', {}).get('accepted', 0) or 0) }}"
- path: [tool_use_rejected]
- type: AddedFieldDefinition
path: [tool_use_rejected]
value: "{{ (record.get('tool_actions', {}).get('edit_tool', {}).get('rejected', 0) or 0) + (record.get('tool_actions', {}).get('write_tool', {}).get('rejected', 0) or 0) + (record.get('tool_actions', {}).get('multi_edit_tool', {}).get('rejected', 0) or 0) + (record.get('tool_actions', {}).get('notebook_edit_tool', {}).get('rejected', 0) or 0) }}"
- path: [core_metrics_json]
- type: AddedFieldDefinition
path: [core_metrics_json]
value: "{{ record.get('core_metrics', {}) | tojson }}"
- path: [tool_actions_json]
- type: AddedFieldDefinition
path: [tool_actions_json]
value: "{{ record.get('tool_actions', {}) | tojson }}"
- path: [model_breakdown_json]
- type: AddedFieldDefinition
path: [model_breakdown_json]
value: "{{ record.get('model_breakdown', []) | tojson }}"
- path: [unique]
- type: AddedFieldDefinition
path: [unique]
value: "{{ record.get('date', '')[:10] }}|{{ record.get('actor', {}).get('type') or '' }}|{{ record.get('actor', {}).get('api_key_name') or record.get('actor', {}).get('email') or '' }}|{{ record.get('terminal_type') or '' }}"
incremental_sync:
type: DatetimeBasedCursor
Expand Down Expand Up @@ -583,11 +607,14 @@ streams:
- $ref: "#/definitions/tenant_id_injection"
- type: AddFields
fields:
- path: [created_by_id]
- type: AddedFieldDefinition
path: [created_by_id]
value: "{{ record.get('created_by', {}).get('id', '') }}"
- path: [created_by_name]
- type: AddedFieldDefinition
path: [created_by_name]
value: "{{ record.get('created_by', {}).get('name', '') }}"
- path: [created_by_type]
- type: AddedFieldDefinition
path: [created_by_type]
value: "{{ record.get('created_by', {}).get('type', '') }}"

# ── Stream 6: claude_admin_workspaces (full refresh, offset pagination)
Expand Down Expand Up @@ -653,7 +680,8 @@ streams:
- $ref: "#/definitions/tenant_id_injection"
- type: AddFields
fields:
- path: [data_residency]
- type: AddedFieldDefinition
path: [data_residency]
value: "{{ record.get('data_residency', {}) | tojson if record.get('data_residency') else '' }}"

# ── Stream 7: claude_admin_workspace_members (full refresh, substream of workspaces) ──
Expand Down Expand Up @@ -750,9 +778,11 @@ streams:
- $ref: "#/definitions/tenant_id_injection"
- type: AddFields
fields:
- path: [workspace_id]
- type: AddedFieldDefinition
path: [workspace_id]
value: "{{ stream_partition['workspace_id'] }}"
- path: [unique]
- type: AddedFieldDefinition
path: [unique]
value: "{{ record.get('user_id', '') }}:{{ stream_partition['workspace_id'] }}"

# ── Stream 8: claude_admin_invites (full refresh, offset pagination)
Expand Down
21 changes: 14 additions & 7 deletions src/ingestion/connectors/ai/cursor/connector.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@ definitions:
mandatory_fields:
type: AddFields
fields:
- path: [tenant_id]
- type: AddedFieldDefinition
path: [tenant_id]
value: "{{ config['insight_tenant_id'] }}"
- path: [source_id]
- type: AddedFieldDefinition
path: [source_id]
value: "{{ config['insight_source_id'] }}"

post_paginator:
Expand Down Expand Up @@ -111,7 +113,8 @@ streams:
- $ref: "#/definitions/mandatory_fields"
- type: AddFields
fields:
- path: [unique_key]
- type: AddedFieldDefinition
path: [unique_key]
value: "{{ config['insight_tenant_id'] }}-{{ config['insight_source_id'] }}-{{ record['id'] }}"

# ── Stream 2: cursor_audit_logs (incremental, GET) ──
Expand Down Expand Up @@ -171,7 +174,8 @@ streams:
- $ref: "#/definitions/mandatory_fields"
- type: AddFields
fields:
- path: [unique_key]
- type: AddedFieldDefinition
path: [unique_key]
value: "{{ config['insight_tenant_id'] }}-{{ config['insight_source_id'] }}-{{ record['event_id'] }}"
incremental_sync:
type: DatetimeBasedCursor
Expand Down Expand Up @@ -276,7 +280,8 @@ streams:
- $ref: "#/definitions/mandatory_fields"
- type: AddFields
fields:
- path: [unique_key]
- type: AddedFieldDefinition
path: [unique_key]
value: "{{ config['insight_tenant_id'] }}-{{ config['insight_source_id'] }}-{{ record['userEmail'] }}-{{ record['timestamp'] }}"
incremental_sync:
type: DatetimeBasedCursor
Expand Down Expand Up @@ -372,7 +377,8 @@ streams:
- $ref: "#/definitions/mandatory_fields"
- type: AddFields
fields:
- path: [unique_key]
- type: AddedFieldDefinition
path: [unique_key]
value: "{{ config['insight_tenant_id'] }}-{{ config['insight_source_id'] }}-{{ record['userEmail'] }}-{{ record['timestamp'] }}"
incremental_sync:
type: DatetimeBasedCursor
Expand Down Expand Up @@ -490,7 +496,8 @@ streams:
- $ref: "#/definitions/mandatory_fields"
- type: AddFields
fields:
- path: [unique_key]
- type: AddedFieldDefinition
path: [unique_key]
value: "{{ config['insight_tenant_id'] }}-{{ config['insight_source_id'] }}-{{ record['userId'] }}-{{ record['date'] }}"
incremental_sync:
type: DatetimeBasedCursor
Expand Down
Loading
Loading